1. 程式人生 > >使用Kettle進行資料遷移(ETL)

使用Kettle進行資料遷移(ETL)

由於開發新的系統,需要將之前一個老的C/S應用的資料按照新的資料設計匯入到新庫中。此過程可能涉及到表結構不一致、大資料量(千萬級,甚至上億)等情況,包括異構資料的抽取、清洗等等工作。部分複雜的工作需要我們的DBA寫程式碼用程式在JDBC或者Delphi中解決,而大部分稍簡單的資料的遷移需要一個強大的ETL工具來解決。某日,技術經理讓我找一個滿足我們專案資料遷移需求的穩定、高效ETL工具。google了幾把,網上大致有下列幾款軟體資料較多:Oracle的OWB(Oracle Warehouse Builder)、AICloudETL、Kettle等等。一一安裝並嘗試,最終因為Kettle資料豐富、成功案例多、可配合強大的任務排程工具來使用而選定用它。經過測試效率基本滿足遷移需要。在2012年7月左右的時候寫了一個簡單的入門文件供專案組內部使用,現在貼出來,供有類似需求的朋友們參考。【之後我們還用Flex+Quartz開發了一個BS的類似於Kettle的資料轉移工具,在我們的專案中每天晚上從一個庫遷移資料到另一個庫。將在之後的博文中大體講述】
一      關於Kettle Kettle是一款國外開源的ETL工具,純java編寫,資料抽取高效穩定的資料遷移工具。Kettle中有兩種指令碼檔案,transformation和job,transformation完成針對資料的基礎轉換,job則完成整個工作流程的控制。 二      本專案中的ETL需求 本專案主要有以下要求: 1、能完成ASCii編碼到UTF8編碼的轉換。 2、穩定。 3、可高效的完成批量資料的轉移。 4、能記錄、檢視(最好能給出分析)轉移過程中失敗的資料。 5、易於使用,學習成本低。 經測試,以上需求Kettle均可滿足,將在之後的操作說明中提及並在最後總結。
三      操作說明3.1軟體獲取 在官網下載,該軟體為綠色版,解壓後點擊Spoon.bat執行,需要JRE環境支援。(此文件中使用4.2.0 stable版本示例) 3.2 基本操作 Kettle左側的功能區有“主物件樹”和“核心物件”兩個面板。其中“核心物件”較為常用。右側為物件的屬性編輯區。可以將左側的物件拖動到右側編輯區。同時按鍵盤shift鍵在兩個物件上畫線,可連線兩個物件。多個物件連線成為一個transformation。 3.3 示例一:Kettle的基本操作和簡單應用 場景要求:此demo假設需抽取***.**.**.33上編碼為US7ASCII的某一張表中資料提取到本地上編碼為UTF-8的庫中。
詳細步驟: 1、雙擊Spoon.bat執行軟體,點選“沒有資源庫”,進入主介面。左上角點選”檔案-新建-轉換“儲存為demo.ktr 2、左側選擇“核心物件”面板。”在“輸入”資料夾下選擇“表輸入”並把它拖動到右側編輯區。 3、雙擊編輯區的“表輸入”圖示,編輯資料輸入來源。點選“資料庫連線”右側的“新建”按鈕,按demo背景中的要求,配置資料庫引數。配置後點擊“Test”,若配置有誤將彈出異常提示,根據提示修正。若無誤將顯示如下資訊: 點選“確定”和“OK”,我們為此表輸入物件確定了資料庫。 4、繼續點選“獲取SQL”查詢語句,選擇輸入表。這裡我們選擇A_GB這張表。 選擇輸入表後,請務必勾選“允許延遲載入”複選框。(否則可能導致亂碼,將在文件最後說明。)其餘選項預設,點選“確定”完成表輸入物件的編輯。       5、在左側“核心物件”中的“轉換”資料夾中選擇“欄位選擇”功能,拖動到右側編輯區。按住鍵盤shift同時滑鼠從“表輸入”為起點,“欄位選擇”為終點畫一條連線。如圖:             6、雙擊“欄位選擇”,開啟編輯視窗,選擇“元資料”面板,點選右側“獲取改變的欄位”,將自動列出之前表輸入中所有欄位。 7、根據要抽取的目標表欄位名(輸出欄位名),給每一個輸入欄位改成和輸出欄位相同的名稱。同時請務必在Encoding一欄中選擇輸出庫的編碼。根據demo的背景要求,此處我們選擇GBK。       8、編輯完“欄位選擇”後點擊“確定”關閉視窗。同上,在“輸出”資料夾中拖動一個“表輸出”到右側編輯區,並畫連線。 9、雙擊“表輸出”開啟其編輯視窗。同“表輸入”一樣,按照demo背景要求,配置好本地庫。       10、同“表輸入”,選擇輸出的目標表。選擇後在“Darabase fileds”面板中點選“Enter field mapping”對映輸入輸出關係。       11、因之前已經在“欄位選擇”中為每一個輸入欄位改名,這裡點“猜一猜”,會根據欄位近似度自動匹配對映關係。 對映完輸入輸出欄位的關係,檢查無誤後,點選“確定”關閉視窗。
      12、至此,我們最簡單的一個抽取示例的轉換建立完畢,點選“校驗這個轉換”,Kettle會校驗並給出簡單的報告。此處只有一個警告,經檢查並不影響我們的抽取轉換工作,點選“關閉”。       13、點選“執行這個轉換”,選擇“本地執行”,點選“啟動”來執行這個轉換。       14、轉換的過程可以在控制檯實時顯示。同時“日誌”的詳細程度是可選的。       15、執行完畢後,控制檯日誌若無異常資訊,說明轉換成功,可以去我們本地庫檢視。發現確實已被匯入新庫,兩者記錄數相同且無亂碼。 3.4示例二:欄位合併、計算等複雜背景下的應用 場景要求:要求資料輸入來自於兩張表,且輸出表的某欄位需兩張輸入表的欄位進行合併。並可能對某些欄位進行字串操作、日期運算、數學計算等。此示例演示字串操作、列合併。日期運算和數學計算與此類似,不再敖述。 簡略步驟: 1、基本操作同示例一,其中需引入“Replace in string”和“Modified JavaScript Value”物件。 2、表輸入:使用一個簡單的關連查詢,查出所有要抽取的欄位和需要合併的列。 3、Replace in string物件:需填寫要被替換的輸入欄位“In Stream field”,這裡我們替換APP_CN_NAME欄位。是否使用正則表示式“useRegEx”選擇“否”,“Search”搜尋字串假設搜尋“PERFETTI VAN”,“Replace with”替換為“Replace in string替換後的內容”。“Whole word”是否整個單詞和“Case sensitive”大小寫敏感均選擇“否”。 4、“Modified JavaScript Value”物件:此物件通過編寫javaScript指令碼來對記錄進行高階操作。Kettle內建mozilla的rhino來執行指令碼,完成對輸入記錄的一系列操作。 左側有大量的字串、日期、數學運算的庫函式可以呼叫。這裡只簡單將兩列合併為新欄位。(若數學、日期運算較複雜,也可以使用“計算器”物件) 此demo中Javascript物件中的值為:
四      Kettle針對此專案的注意事項4.1 編碼問題 專案要求能完成ASCii編碼到UTF8編碼的轉換。資料顯示Kettle預設輸入、輸出均使用UTF-8編碼。為保證不亂碼需注意: 輸入:此專案的輸入是ASCii,故在“表輸入”編輯面板務必勾選“允許延遲轉換”,便會根據資料庫自身的編碼讀入。否則將會預設以UTF-8讀入,可能導致亂碼。
輸出:在輸出前請使用“欄位選擇”物件。同時在“欄位選擇”的“元資料”面板中設定輸出編碼。可以指定任意輸出字符集。
4.2 效率問題 專案要求ETL工具需高效的完成批量資料的轉移。檢視日誌發現Kettle每次輸入5W條記錄,經過處理再輸出。經測試,100W條記錄,從172.16.4.33至本地,耗時14min22s。 4.3異常資訊 由於Kettle由Java編寫,出錯時,其異常資訊也按照Java異常資訊格式列印。如圖某錯誤的日誌為: 其資訊是: 13.11.42 by buildguy) : org.pentaho.di.core.exception.KettleDatabaseBatchException: 2012/07/10 09:42:32 - 表輸出.0 - ERROR (version 4.2.0-stable, build 15748 from 2011-09-08 13.11.42 by buildguy) : Error updating batch 2012/07/10 09:42:32 - 表輸出.0 - ERROR (version 4.2.0-stable, build 15748 from 2011-09-08 13.11.42 by buildguy) : ORA-12899: 列 "SCOTT"."T_TMAAS_APP_TMXZ_APPFORM"."APP_NUM" 的值太大 (實際值: 9, 最大值: 4) 由以上異常資訊可明顯看出在批量更新時出錯,錯誤在“表輸出”時出現,具體原因是SCOTT使用者下的T_TMAAS_APP_TMXZ_APPFORM表的APP_NUM欄位的輸出值太大。經檢查,該欄位最大長度為4,合併後向其輸出的長度為9,故拋此異常。 此資訊會對異常有較準確的範圍描述和簡單的原因分析,有利於分析。但未標明是哪一條記錄導致。(由於ETL過程可能有複雜的表關聯和欄位處理,產生異常不一定是輸入流中資料的問題,可也能是關聯問題、指令碼將欄位變換後和輸出不匹配等問題。尤其是關聯後的記錄經指令碼處理後與輸出表結構不匹配時,軟體難以定位原始記錄,需人工分析。) 4.4、易用性 Kettle由Java編寫,在生產中可方便地與Java專案整合,配合任務排程工具可完成強大的ETL工作,使用較為廣泛,參考資料豐富。