SSIS体系结构控制流和数据流技术对比分析

存储技术

595人已加入

描述

在SSIS的体系结构中,Package是SSIS的最重要的部分,从本质上来讲,Package是一个有序地执行任务的单元。Package的核心是控制流(Control Flow),用于协调包中所有组件的执行顺序。数据流(Data Flow)是控制流中的核心组件,用于把数据提取到服务器内存中,转换数据并把数据写入到目标结构中。

一,控制流

控制流用于协调包中所有组件的执行顺序,这些组件由Task和容器构成,并且受到优先约束的控制。

控制流由三大组件构成,分别是Task,容器和优先约束。

容器用于把Task集合到一起,除了视觉上的分组外,容器还允许用户定义作用域在容器范围内的变量和事件处理程序。

Task是一个独立的工作单元,为包提供了实现特定功能的接口。

优先约束不仅把Task连接到一起,而且指定Task执行的顺序。

Task按照优先约束(Precedence Constraint)规定的顺序执行下去。在一个Task工作之前,Package必须完成其前面Task,不管前面的Task执行的结果是成功、失败或者完成。

1,优先约束

优先约束是把Task连接到一起的连接器,而且定义了Task的执行顺序。优先约束定义了Task的执行路径和条件,只有满足优先约束的条件时,才能按照连接路径继续执行下一个Task。例如,在下图所示的控制流中,优先约束把Execute SQL Task和 Data Flow Task连接到一起,并且规定只有Execute SQL Task都执行完成之后,才会执行Data Flow Task。

为两个Task创建优先约束,必须设置约束值或表达式,当约束值或表达式为True时,满足约束条件。

优先约束的求值运算(Evaluation operation)有四种:

约束(Constraint),根据约束的结果来确定约束的状态

表达式(Expression),根据表达式的结果来确定约束的状态

表达式和约束(Expression and Constraint),根据表达式和约束结果的组合来确定约束的状态

表达式或约束(Expression or Constraint),根据表达式或约束的结果之一来确定约束的状态

根据约束选项的不同,约束值有Value和表达式两种类型:

当求值选项为约束时,约束值有:成功(Success)、失败(Failure)和完成(Completion);

当求值选项为表达式时,需要用户编写表达式;

约束值共有三种有效值,他们的含义是:

成功约束:表示只有在前置任务或容器成功时,才会执行当前的任务;

失败约束:表示只有在前置任务或容器失败时,才会执行当前的任务;

完成约束:表示只有在前置任务或容器完成(不管失败或成功)时,才会指定当前的任务

当一个Task上创建了多个约束时,必须设置多个约束的逻辑组合。当设置为逻辑与时,多个优先约束同时为True,才满足优先约束的条件;当设置为逻辑或时,只要有一个约束为True,就满足优先约束的条件。多重约束使当前Task在前置任务都成功(逻辑与)的情况下,或者任意一个前置任务成功(逻辑或)的情况下执行。

2,优先约束控制Task的并发

控制流不能在Task组件之间传递数据,它担当Task的调度者,用于串行或并行执行任务。如果两个Task之间没有设置优先约束,那么这两个Task是并发执行的。在设计Package时,应该最大限度地提高Task组件的并发处理能力,这样能够充分利用服务器的系统资源,有助于减少ETL执行的时间。

3,Task组件通过优先约束保持同步

在Task组件之间设置优先约束,只有在上游Task执行完成之后,才会执行下游Task;在上游Task执行完成之前,下游Task不会执行。因此,Task是同步的。

Task的同步表现在两个方面:

Task之间:一个Task在将操作移交之前必须完成(成功,失败或完成),一个Task要想运行,其所有上游Task必须全部完成,否则不会执行。Task的执行顺序由优先约束定义。

单个Task:Task在执行完成之前,不会释放SSIS的执行线程,即执行SSIS Task对服务器的线程资源是独占的,直至Task 完成,否则不会释放线程资源。

二,数据流

数据流(Data Flow)是控制流中的核心组件,用于把数据提取到服务器内存中,转换数据并把数据写入到目标结构中。由于数据流任务把数据加载到服务器内存中进行转换,因此,SSIS属于内存中的ETL工具,这使得SSIS可以高效地执行数据的转换操作。数据流的核心功能是把数据提取到服务器的内存中,转换数据之后,把数据写入到另一个目的中。数据从源移动到目的,使用的是内存管道(Pipeline)。当数据在管道中时,你可以使用转换组件对这些数据进行清洗和处理。

数据流具有流的特性,数据的提取,转换和加载是同时进行的。SSIS引擎以流的形式对数据进行并发处理,这意味着数据不是一次性全部加载,而是划分为不重复的多个部分,组成一个流,源源不断地从上游组件流向下游组件。在数据流动的过程中,数据流的所有转换组件同时对数据流进行处理。上游组件处理完一批数据之后,交接给下游组件继续处理,同时,上游组件继续处理下一批数据。数据在组件之间流动,各个组件同时处理数据的不同部分,直到全部数据处理完成。

数据流具有反馈和自动调节的功能,如果下游组件的处理速度存在压力,那么SSIS将会向上游组件施加反向压力,SSIS引擎感受到压力,将启动自动调节机制,使上游组件的数据流动速度减缓,从而达到动态平衡。

数据流任务由四部分组成:源,转换、目的和路径,分别用于把数据加载到内存中,对内存中的数据进行转换,并内存中的数据转移到目标中,数据按照路径来“移动”:

:用于指定外部数据源位置,把外部数据加载到内存中,向下游组件输出数据。

转换:转换是在内存中完成的,用于对管道中的数据进行更改,影响内存数据管道内的数据,是数据流的核心功能。

目的:在数据管道的终点,数据离开数据管道,把数据输出到外部存储。

路径:数据流组件之间的连线叫做路径,数据按照路径来转移,可以视为数据走的路线。

外部数据源是数据管道的源泉,通常表示为连接(Connection),SSIS通过连接去访问外部数据源,连接管理器用于设置连接的属性,主要是用于用于集中设置访问数据源的连接字符串,该连接管理器可以被多个组件共享,也可以被多个Package共享。

1,数据流的缓冲区

数据管道是数据流通的管道线,数据流使用内存暂时存储数据流中的数据,这意味着,把数据从外部源提取到SSIS引擎时,数据会存储在预先分配好的内存缓冲区中,可以根据数据行的宽度(一个row中所有column的字节数),设置DefaultBufferMaxRows属性调整缓存区可以容纳的最大数据行数量,或直接设置DefaultBufferSize属性来调整缓冲区的大小。

数据流的缓冲区可以理解为一个二维表,每行有固定的长度,每一列的位置都是固定的。SSIS 引擎根据服务器的资源和压力,预先分配一组缓冲区,每一个缓冲区存储完整数据集的一个不重复子集。当对数据流进行转换处理时,SSIS 引擎后台使用一种更为有效的方式:对同一个缓冲区,逐个应用转换组件,这比把转换后的数据复制到另一个缓冲区,然后应用下一个转换组件更为有效。不过,有些情况下,SSIS引擎需要复制缓冲区,甚至需要拦截数据流,然后对整个数据集进行转换处理,例如,聚合和排序。

SSIS 引擎处理数据最理想的情况是:所有的转换施加在同一个缓冲区中,就地执行转换处理数据。但是,现实情况不总是理想的,有些转换组件需要复制缓冲区,才能向下游传递数据。

数据流通过转换组件时,SSIS 引擎是否需要复制缓冲区,跟转换的阻塞特性和通信机制有关。

2,转换的阻塞特性:非阻塞(流),半阻塞和阻塞

非阻塞:立即把数据从管道中传递到下游的转换

半阻塞:把数据增加到一定数量后再传递到下游的转换

阻塞:在接收全部数据之后,再传递到下游的转换

大多数转换都是流式的,这意味着在转换应用到某一行时,不会阻止数据移动到下一个转换。排序转换和聚合转换是阻塞的,这意味着每种转换在向一个转换传递数据之前,需要使用完整的数据集,在转换结束之前,不会向下游组件释放任何数据。通过在数据流镇南关使用一个阻塞转换组件,数据流将被拦截,所有行都将停留在阻塞转换组件中,直到最后一行流进转换组件。

阻塞转换是非常低效的和资源消耗大的,因为所有数据都被拦截,所以server必须使用大量的内存来存储数据,或者如果Server没有足够的内存,那么Server会将部分数据暂存在磁盘上,从而导致IO开销;因为要对大量的数据进行排序,聚合等操作,需要消耗大量的CPU资源和内存资源。

3,转换组件的通信机制

转换组件的通信是指转换组件把数据传递给下一个转换组件,如果输入所使用的缓冲区和输出所使用的缓冲区不一样,那么转换的输出就是异步的,换句话说,异步转换组件不能够既执行指定操作又维护缓存区(行数或者行的顺序),所以必须复制数据,以实现所期望的结果。异步转换组件接收上游组件的输出缓冲区,然后创建新的缓冲区,输出到下一个组件。

如果输入所使用的缓冲区和输出所使用的缓冲区相同,那么转换的输出是同步的,同步转换组件不会创建新的缓冲区,而是复用缓冲区。

缓冲区的生命周期,是从创建缓冲区开始,到异步转换组件截止。由于异步转换组件需要创建额外的缓冲区,消耗Server的内存资源,降低Server处理数据的性能,因此理想的Package Design是一个Data Flow 只使用一个缓冲区完成所有的转换处理操作,所有的转换都是同步输出的。在实际的工作中,我们可以尽量不适用异步转换组件,或是减少缓冲区创建的数量,尽量延长缓冲区的生命周期。

4,识别转换的同步输出和异步输出

数据流的缓冲区可以看作是一个二维表,每行有固定的长度,每列的位置都是固定的,因此一列在同一个缓冲区中的标识符是相同的。如果该列复制到新的缓冲区中,那么,该列的标识符发生变化。SSIS Engine使用LineageID属性来标识缓冲区中的每一列。

在转换组件的高级编辑器中,每列都有一个LineageID属性,这是一个指向缓冲区的指针,标识该列在缓冲区中的位置。

如果转换输出是同步的,那么同一列的LineageID属性在转换的输出和输入中是相同的,如果转换输出是异步的,那么同一列的LineageID属性在转换的输出和输入中是不同的。

例如,Column1 的初始LineageID值是193,如果转换输出是同步的,在转换的Input和Output中,可以看到Column1的LineageID是193.

5,数据流缓冲区的申请和释放

数据源组件会创建新的缓冲区,并为相应的数据列分配LineageID值。

当缓冲区数据被加载到数据目的组件之后,数据目的组件会释放缓冲区。

异步转换组件会终止输入缓冲区,新建输出缓冲区。

同步转换组件复用输入缓冲区,并作为输出缓冲区,传递给下一个转换组件。

三,异步转换示例

异步转换输出是指:转换的输入缓冲区和输出缓冲区不同,对于只包含OLE DB Source和Sort转换的数据流任务,在Sort转换中,输出列有LineageID属性,当数据列第一次被存储到数据流中,SSIS引擎确定该列的LineageID,用于标识数据流的缓存区的位置。

1,数据源组件

数据源组件含有外部列和输出列,外部列直接来源于外部数据源,输出列是数据源向下游输出的数据。数据源组件创建缓冲区,将外部数据加载到缓冲区中,并为缓存区分配LineageID,这个缓冲区就是数据源组件的输出。

Package

2,Sort 组件

Sort组件接收数据源组件的输出数据,对于Sort组件的输入(Sort Input),ID 列的LineageID是197,这跟数据源的输出的ID列的LineageID属性相同,这说明,Sort 转换直接使用数据源的输出作为Sort转换的输入。

Package

Sort 转换的输出(Sort Output),ID列的LineageID属性值是 288,之所以存在不同的LineageID值,是因为Sort转换的输出是异步的,输入缓冲区和输出缓冲区不同,因此,Sort转换的输出需要一个新的列标识符。

SortColumnID属性用于指定跟输出列相关的输入列的LineageID,输出列ID的SortColumnID属性值是197,是输入列的LineageID。

所有具有半阻塞性和阻塞性的转换都是异步输出的,这些转换不会直接向下游传递输入缓冲区,因为需要拦截数据以进行处理和重组。

四,同步转换示例

条件分离转换(Conditional Split)是非阻塞组件,在数据流任务中,使用条件分离组件,把数据源组件的输出按照特定的条件分开流向不同的目的。

1,Conditional Split组件

打开Conditional Split的编辑器,选中Case1,查看属性SynchronousInPutIDIdentificationString

IdentificationString:用于指定组件的数据流,其值具有特定格式的字符串,例如: Conditional Split.Inputs[conditional Split input],

SynchronousInPutID:用于指定跟组件的输出相关的行的输入ID,其值是输入的IdentificationString。

如果组件的属性SynchronousInPutID为None,说明组件会创建新的输出流,转换输出是异步的,如果组件的属性SynchronousInPutID 是一个IdentificationString,说明组件的输出和输入使用相同的缓冲区。

选中 Conditional Split的输入,查看属性IdentificationString的值,和组件的输出Case1的SynchronousInPutID属性值相同。

2,验证LineageID值

查看Sort组件的Input Columns,ID列的LineageID是 197,和数据源组件的输出,Conditional Split的输入都相同,说明Conditional Split没有创建新的数据缓冲区,而是直接使用数据源创建的缓冲区进行转换。

结论:在同步转换输出中,当完成了转换逻辑之后,会立即将缓冲区传递到下游的转换,即转换输入和转换输出使用相同的缓冲区,避免复制缓冲区到输出,因此相同列的LineageID是相同的。

用户可以通过高级编辑器识别同步转换组件和异步转换组件,查看输出的SynchronousInPutID属性,如果SynchronousInPutID属性值为None,那么该组件输出是异步的,如果该值不是None,而是IdentificationString 格式的字符串,那么该转换是同步的。
编辑:hfy

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分