在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,這個緩沖區就是數據源組件的輸出。
2,Sort 組件
Sort組件接收數據源組件的輸出數據,對于Sort組件的輸入(Sort Input),ID 列的LineageID是197,這跟數據源的輸出的ID列的LineageID屬性相同,這說明,Sort 轉換直接使用數據源的輸出作為Sort轉換的輸入。
Sort 轉換的輸出(Sort Output),ID列的LineageID屬性值是 288,之所以存在不同的LineageID值,是因為Sort轉換的輸出是異步的,輸入緩沖區和輸出緩沖區不同,因此,Sort轉換的輸出需要一個新的列標識符。
SortColumnID屬性用于指定跟輸出列相關的輸入列的LineageID,輸出列ID的SortColumnID屬性值是197,是輸入列的LineageID。
所有具有半阻塞性和阻塞性的轉換都是異步輸出的,這些轉換不會直接向下游傳遞輸入緩沖區,因為需要攔截數據以進行處理和重組。
四,同步轉換示例
條件分離轉換(Conditional Split)是非阻塞組件,在數據流任務中,使用條件分離組件,把數據源組件的輸出按照特定的條件分開流向不同的目的。
1,Conditional Split組件
打開Conditional Split的編輯器,選中Case1,查看屬性SynchronousInPutID和IdentificationString:
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
評論
查看更多