Kettle 增量更新設計技巧
首先你需要判斷你是否在處理一個維表,如果是一個維表的話,那么這可能是一個SCD情況,可以使用Kettle的Dimension Lookup 步驟來解決這個問題,如果你要處理的是事實表,方法就可能有所不同,它們之間的主要區別是主鍵的判斷方式不一樣。
事實表一般都數據量很大,需要先確定是否有變動的數據處在某一個明確的限定條件之下,比如時間上處在某個特定區間,或者某些字段有某種限定條件,盡量最大程度的先限定要處理的結果集,然后需要注意的是要先根據id 來判斷記錄的狀態,是不存在要插入新紀錄,還是已存在要更新,還是記錄不存在要刪除,分別對於id 的狀態來進行不同的操作。
處理刪除的情況使用Delete步驟,它的原理跟Insert / Update 步驟一樣,只不過在找到了匹配的id之后執行的是刪除操作而不是更新操作,然后處理Insert / Update 操作,你可能需要重新創建一個轉換過程,然后在一個Job 里面定義這兩個轉換之間的執行順序。
如果你的數據變動量比較大的話,比如超過了一定的百分比,如果執行效率比較低下,可以適當考慮重新建表。
另外需要考慮的是維表的數據刪除了,對應的事實表或其他依賴於此維表的表的數據如何處理,外鍵約束可能不太容易去掉,或者說一旦去掉了就可能再加上去了,這可能需要先處理好事實表的依賴數據,主要是看你如何應用,如果只是簡單的刪除事實表數據的話還比較簡單,但是如果需要保留事實表相應記錄,可以在維表中增加一條記錄,這條記錄只有一個主鍵,其他字段為空,當我們刪除了維表數據后,事實表的數據就更新指向這條空的維表記錄。
定時執行增量更新
可能有時候我們就是定時執行更新操作,比如每天或者一個星期一次,這個時候可以不需要在目標表中增加一個時間戳字段來判斷ETL進行的最大時間,直接在取得原數據庫的時間加上限定條件比如:
Startdate > ? and enddate < ?
或者只有一個startdate
Startdate > ? (昨天的時間或者上個星期的時間)
這個時候需要傳一個參數,用get System Info 步驟來取得,而且你還可以控制時間的精度,比如到天而不是到秒的時間。
當然,你也需要考慮一下如果更新失敗了怎么處理,比如某一天因為某種原因沒有更新,這樣可能這一天的記錄需要手工處理回來,如果失敗的情況經常可能發生,那還是使用在目標數據庫中增加一個時間字段取最大時間戳的方式比較通用,雖然它多了一個很少用的字段。
執行效率和復雜度
刪除和更新都是一項比較耗費時間的操作,它們都需要不斷的在數據庫中查詢記錄,執行刪除操作或更新操作,而且都是一條一條的執行,執行效率低下也是可以預見的,盡量可能的縮小原數據集大小。減少傳輸的數據集大小,降低ETL的復雜程度
時間戳方法的一些優點和缺點
優點: 實現方式簡單,很容易就跨數據庫實現了,運行起來也容易設計
缺點:浪費大量的儲存空間,時間戳字段除ETL過程之外都不被使用,如果是定時運行的,某一次運行失敗了,就有可能造成數據有部分丟失.
其他的增量更新辦法:
增量更新的核心問題在與如何找出自上次更新以后的數據,其實大多數數據庫都能夠有辦法捕捉這種數據的變化,比較常見的方式是數據庫的增量備份和數據復制,利用數據庫的管理方式來處理增量更新就是需要有比較好的數據庫管理能力,大多數成熟的數據庫都提供了增量備份和數據復制的方法,雖然實現上各不一樣,不過由於ETL的增量更新對數據庫的要求是只要數據,其他的數據庫對象不關心,也不需要完全的備份和完全的stand by 數據庫,所以實現方式還是比較簡單的.,只要你創建一個與原表結構類似的表結構,然后創建一個三種類型的觸發器,分別對應insert , update , delete 操作,然后維護這個新表,在你進行ETL的過程的時候,將增量備份或者數據復制停止,然后開始讀這個新表,在讀完之后將這個表里面的數據刪除掉就可以了,不過這種方式不太容易定時執行,需要一定的數據庫特定的知識。如果你對數據的實時性要求比較高可以實現一個數據庫的數據復制方案,如果對實時性的要求比較低,用增量備份會比較簡單一點。
幾點需要注意的地方:
1. 觸發器
無論是增量備份還是數據復制,如果原表中有觸發器,在備份的數據庫上都不要保留觸發器,因為我們需要的不是一個備份庫,只是需要里面的數據,最好所有不需要的數據庫對象和一些比較小的表都不用處理。
2. 邏輯一致和物理一致
數據庫在數據庫備份和同步上有所謂邏輯一致和物理一致的區別,簡單來說就是同一個查詢在備份數據庫上和主數據庫上得到的總的數據是一樣的,但是里面每一條的數據排列方式可能不一樣,只要沒有明顯的排序查詢都可能有這種情況(包括group by , distinct , union等),而這可能會影響到生成主鍵的方式,需要注意在設計主鍵生成方式的時候最好考慮這一點,比如顯式的增加order 排序. 避免在數據出錯的時候,如果需要重新讀一遍數據的時候主鍵有問題.
總結
增量更新是ETL中一個常見任務,對於不同的應用環境可能采用不同的策略,本文不可能覆蓋所有的應用場景,像是多個數據源匯到一個目標數據庫,id生成策略,業務主鍵和代理主鍵不統一等等,只是希望能給出一些思路處理比較常見的情況,希望能對大家有所幫助。