開篇介紹
通常一個 ETL Package 是由多個控制流和數據流共同組成,有的時候 ETL 的步驟可能會比較多,整個流程執行下來的時間可能比較長。假設在 ETL Package 中包含5個Task,前3個Task執行超過1個小時,到了第4個Task的時候發生失敗。如果下次執行的時候重新從第1個任務開始執行,那么又要花費1個小時等待 1-3 任務執行,無疑在效率上講是非常低的。特別是在數據倉庫的應用上,往往從數據源到Staging的過程中有千萬級甚至億級的數據要加載,加載完畢之后再進入到維度和事實表。如果在進入維度和事實表的過程中發生失敗,就意味着下次需要重新加載數據到Staging表。而通過檢查點CheckPoint的設置可以解決這個問題,通過合理的設置可以跳過上一次已經成功執行過一些步驟而直接從失敗的地方重新開始執行,這樣大大的提高了包的執行效率。
案例演示
下面這個 ETL 示例簡單的模擬了從一個數據源抽取數據然后輸出到一個數據表和一個平面文件的過程,之后再看 CheckPoint 的使用。
USE BIWORK_SSIS GO IF OBJECT_ID('CK_Address') IS NOT NULL DROP TABLE CK_Address GO IF OBJECT_ID('CK_AddressAudit') IS NOT NULL DROP TABLE CK_AddressAudit GO CREATE TABLE CK_Address ( AddressID INT, AddressLine1 NVARCHAR(60), AddressLine2 NVARCHAR(60), City NVARCHAR(30) ) CREATE TABLE CK_AddressAudit ( ID INT PRIMARY KEY IDENTITY(1,1), CityName NVARCHAR(60), Counts INT )
ETL 過程 -
- EST_TruncateAddress - TRUNCATE TABLE dbo.CK_Address TRUNCATE TABLE dbo.CK_AddressAudit
- DFT_LoadAddress - 從 AdventureWorks2012.People.Address 中抽取數據到 dbo.CK_Address 中
- DFT_SaveAddressAudit - 對 CK_Address 表中的數據做出一些統計然后寫入到 dbo.CK_AddressAudit 中
- DFT_OutputAddressAudit - 將 dbo.CK_AddressAudit 中的數據輸出到一個文本文件中
輸出結果- CK_Address 和 CK_AddressAudit
輸出的文件
假設在最后一個步驟發生錯誤,那么在下次執行 Package 的時候,前面所有的步驟都需要被重新執行。
CheckPoint 的設置過程
通過設置 CheckPoints 可以解決這個問題,要使用檢查點首先要在包中開啟檢查點這一功能,並且可以在相應的容器和控制流 Task 中寫檢查點。
第一步,找到 SSIS Package 的屬性,設置 SaveCheckPoints 屬性為 Ture,這樣就允許 SSIS Package 在執行過程中保存檢查點。
第二步,在 CheckPointFileName 屬性中,提供一個文件名和路徑,這樣 SSIS Package 就會用這個文件來維護執行過程中的狀態信息。假設一個包執行失敗了然后重新啟動它,那么包就可以讀這個檢查點文件來找到最后一次執行成功的 Task 然后決定從哪里開始重新執行,一個包只能有一個檢查文件。
第三步,設置 CheckpointUsage 屬性為 IfExists。這樣如果檢查點文件不存在的時候包會從頭開始執行,如果存在就會根據相應的狀態信息從指定的 Task 開始執行。
第四步,當在包中啟用了檢查點信息的話,最后的一個步驟就是在包中各種 Task 上來設置檢查點,這時需要將相應的容器或者Task的 FailPackageOnFailure 屬性設置為 True,此處修改的是 DFT_OutputAddressAudit 屬性。
設置保存完 SSIS Package 之后再次運行,仍然在 DFT_OutputAddressAudit 處會發生錯誤,並且 SSIS Package 會輸出一個檢查點文件。
可以看看這個檢查點文件。
<DTS:Checkpoint xmlns:DTS="www.microsoft.com/SqlServer/Dts" DTS:PackageID="{66363AAC-346A-4225-BE24-34538C1DF296}"> <DTS:Variables DTS:ContID="{66363AAC-346A-4225-BE24-34538C1DF296}"/> <DTS:Container DTS:ContID="{FCABC727-26BD-4C73-AA26-2B31BCC2C3E1}" DTS:Result="0" DTS:PrecedenceMap="Y"/> <DTS:Container DTS:ContID="{11182445-3759-4699-88E8-345105620B53}" DTS:Result="0" DTS:PrecedenceMap=""/> <DTS:Container DTS:ContID="{DA2ED97D-2D6E-4401-A36E-1A9A28B51C37}" DTS:Result="0" DTS:PrecedenceMap=""/> <DTS:Container DTS:ContID="{5DC475B3-C3DC-4118-8116-4DC1FF8CA5E2}" DTS:Result="0" DTS:PrecedenceMap="Y"/> </DTS:Checkpoint>
修改好 DFT_OutputAddressAudit 然后再次運行,發現這次直接是從 DFT_OutputAddressAudit 處開始執行,這樣就不需要重復執行已經成功過的步驟。
執行成功之后,這個檢查點文件將會被 SSIS Package 刪除掉。
CheckPoint 執行過程解析
啟用了檢查點的 Package 在重新執行的時候它的執行過程通常是這樣的:
第一步,檢查 Checkpoints 文件是否存在。如果不存在的話,那么包將從頭開始執行。如果存在,包將讀取這個文件並找到應該從哪一個 Task 開始執行。並且也會從中讀取一些有關如何從上一次失敗的時候要如何更新相應的變量和連接信息。
第二步,更新每一個設置過 Checkpoint (FailPackageOnFailure = True) 的那些已經執行成功的Task的狀態,記錄下來更新到 Checkpoint 文件。
第三步,如果包執行失敗,那么 Checkpoint 文件將不會改變並只會保留上一次執行成功的 Task 的信息。
第四步,如果包執行成功,那么 Checkpoint 文件就會被刪除掉。那么下一次包再運行的時候,Checkpoint 文件將不會存在,這樣包又會繼續從第一個 Task 開始執行。
如果將 CheckpointUsage 屬性設置為 Always, 那么檢查文件必須存在否則包將不會執行。另外,如果包設置了 TransactionOption = Required 的話,將不允許使用 Checkpoints 這一機制。
在一個包有着非常多而復雜的子流程情況下,無疑通過啟用檢查點將會節省大量的時間,因為它可以跳過那些在上一次已經成功的 Task 而直接從失敗的 Task 那里重新執行。當然在 Data Flow Task 上可以設置檢查點,但是對於在 Data Flow Task 內部將不能設置,因為 Checkpoint 只支持到 Control Flow Task 這一層,而不會支持 Data Flow 這一層。
更多 BI 文章請參看 BI 系列隨筆列表 (SSIS, SSRS, SSAS, MDX, SQL Server) 如果覺得這篇文章看了對您有幫助,請幫助推薦,以方便他人在 BIWORK 博客推薦欄中快速看到這些文章。