ETL利器Kettle實戰應用
本系列文章主要索引如下:
本文主要閱讀目錄如下:
ETL(Extract-Transform-Load的縮寫,即資料抽取、轉換、裝載的過程),對於企業或行業應用來說,我們經常會遇到各種資料的處理,轉換,遷移,所以瞭解並掌握一種etl工具的使用,必不可少,這裡我介紹一個我在工作中使用了3年左右的ETL工具Kettle,本著好東西不獨享的想法,跟大家分享碰撞交流一下!在使用中我感覺這個工具真的很強大,支援圖形化的GUI設計介面,然後可以以工作流的形式流轉,在做一些簡單或複雜的資料抽取、質量檢測、資料清洗、資料轉換、資料過濾等方面有著比較穩定的表現,其中最主要的我們通過熟練的應用它,減少了非常多的研發工作量,提高了我們的工作效率,不過對於我這個.net研發者來說唯一的遺憾就是這個工具是Java編寫的。
1、Kettle概念
Kettle是一款國外開源的ETL工具,純java編寫,可以在Window、Linux、Unix上執行,綠色無需安裝,資料抽取高效穩定。
Kettle 中文名稱叫水壺,該專案的主程式設計師MATT 希望把各種資料放到一個壺裡,然後以一種指定的格式流出。
Kettle這個ETL工具集,它允許你管理來自不同資料庫的資料,通過提供一個圖形化的使用者環境來描述你想做什麼,而不是你想怎麼做。
Kettle中有兩種指令碼檔案,transformation和job,transformation完成針對資料的基礎轉換,job則完成整個工作流的控制。
2、下載和部署
下載kettle壓縮包,因kettle為綠色軟體,解壓縮到任意本地路徑即可3、Kettle環境配置(有Java環境的直接忽略此章節)
3、1 安裝java JDK
1)首先到官網上下載對應JDK包,JDK1.5或以上版本就行;
2)安裝JDK;
3)配置環境變數,附配置方式:
安裝完成後,還要對它進行相關的配置才可以使用,先來設定一些環境變數,對於Java來說,最需要設定的環境變數是系統路徑變數path。
(1)要開啟環境變數的設定視窗。右擊“我的電腦”,在彈出的快捷選單中選擇“屬性”選項,進入“系統屬性”對話方塊,如圖所示。選擇“高階”標籤,進入“高階”選項卡,再單擊“環境變數”按鈕,進入“環境變數”對話方塊,如圖所示:
(2)在“Administrator的使用者變數”列表框中,選擇變數PATH,待其所在行變高亮後,單擊“編輯”按鈕,如圖所示。
(3)在彈出的“編輯系統變數”對話方塊中,將JDK安裝路徑下的bin目錄路徑設定到Path變數中,如圖所示。
編輯完後,單擊“確定”按鈕,進行儲存,環境變數Path的設定就正式完成。
注意:設定Path變數的路徑,必須是JDK安裝目錄中的bin目錄,有時候在JDK安裝目錄的同一層會有JRE的安裝目錄,因此請謹慎選取相關路徑,避免將路徑設定成JRE目錄下的bin目錄。
3、2 測試JDK配置是否成功
設定好環境變數後,就可以對剛設定好的變數進行測試,並檢測Java是否可以執行。
(1)單擊“開始”按鈕,選擇“執行”選項,在“執行”對話方塊中輸入cmd命令。
(2)之後單擊“確定”按鈕,開啟命令列視窗。
(3)在游標處輸入:javac命令,按下Enter鍵執行,即可看到測試結果
3、3 執行Kettle
進入到Kettle目錄,如果Kettle部署在windows環境下,雙擊執行spoon.bat或Kettle.exe檔案,出現如下介面: 這樣配置環境這一塊基本上就完成了。 4、Kettle使用及元件介紹 4.1 Kettle使用 Kettle提供了資源庫方式的方式來整合所有的工作,但是因為資源庫移植不方便,所以我們選擇沒有資源庫; 1)建立一個新的transformation,點選 儲存到本地路徑,例如儲存到D:/etltest下,儲存檔名為EtltestTrans,kettle預設transformation檔案儲存後後綴名為ktr; 2)建立一個新的job,點選 儲存到本地路徑,例如儲存到D:/etltest下,儲存檔名為EtltestJob,kettle預設job檔案儲存後後綴名為kjb; 4.2 元件樹介紹
|
Main Tree選單列出的是一個transformation中基本的屬性,可以通過各個節點來檢視。 DB連線:顯示當前transformation中的資料庫連線,每一個transformation的資料庫連線都需要單獨配置。 Steps:一個transformation中應用到的環節列表 Hops:一個transformation中應用到的節點連線列表 |
Core Objects選單列出的是transformation中可以呼叫的環節列表,可以通過滑鼠拖動的方式對環節進行新增。 Input:輸入環節 Output:輸出環節 Lookup:查詢環節 Transform:轉化環節 Joins:連線環節 Scripting:指令碼環節 |
類別 |
環節名稱 |
功能說明 |
Input |
文字檔案輸入 |
從本地文字檔案輸入資料 |
表輸入 |
從資料庫表中輸入資料 |
|
獲取系統資訊 |
讀取系統資訊輸入資料 |
|
Output |
文字檔案輸出 |
將處理結果輸出到文字檔案 |
表輸出 |
將處理結果輸出到資料庫表 |
|
插入/更新 |
根據處理結果對資料庫表機型插入更新,如果資料庫中不存在相關記錄則插入,否則為更新。會根據查詢條件中欄位進行判斷 |
|
更新 |
根據處理結果對資料庫進行更新,若需要更新的資料在資料庫表中無記錄,則會報錯停止 |
|
刪除 |
根據處理結果對資料庫記錄進行刪除,若需要刪除的資料在資料庫表中無記錄,則會報錯停止 |
|
Lookup |
資料庫查詢 |
根據設定的查詢條件,對目標表進行查詢,返回需要的結果欄位 |
流查詢 |
將目標表讀取到記憶體,通過查詢條件對記憶體中資料集進行查詢 |
|
呼叫DB儲存過程 |
呼叫資料庫儲存過程 |
|
Transform |
欄位選擇 |
選擇需要的欄位,過濾掉不要的欄位,也可做資料庫欄位對應 |
過濾記錄 |
根據條件對記錄進行分類 |
|
排序記錄 |
將資料根據某以條件,進行排序 |
|
空操作 |
無操作 |
|
增加常量 |
增加需要的常量欄位 |
|
Scripting |
Modified Java Script Value |
擴充套件功能,編寫JavaScript指令碼,對資料進行相應處理 |
Mapping |
對映(子轉換) |
資料對映 |
Job |
Sat Variables |
設定環境變數 |
Get Variables |
獲取環境變數 |
Main Tree選單列出的是一個Job中基本的屬性,可以通過各個節點來檢視。 DB連線:顯示當前Job中的資料庫連線,每一個Job的資料庫連線都需要單獨配置。 Job entries:一個Job中引用的環節列表 |
|
Job entries選單列出的是Job中可以呼叫的環節列表,可以通過滑鼠拖動的方式對環節進行新增。 每一個環節可以通過滑鼠拖動來將環節新增到主視窗中。 並可通過shift+滑鼠拖動,實現環節之間的連線。 |
類別 |
環節名稱 |
功能說明 |
Job entries |
START |
開始 |
DUMMY |
結束 |
|
Transformation |
引用Transformation流程 |
|
Job |
引用Job流程 |
|
Shell |
呼叫Shell指令碼 |
|
SQL |
執行sql語句 |
|
FTP |
通過FTP下載 |
|
Table exists |
檢查目標表是否存在,返回布林值 |
|
File exists |
檢查檔案是否存在,返回布林值 |
|
Javascript |
執行JavaScript指令碼 |
|
Create file |
建立檔案 |
|
Delete file |
刪除檔案 |
|
Wait for file |
等待檔案,檔案出現後繼續下一個環節 |
|
File Compare |
檔案比較,返回布林值 |
|
Wait for |
等待時間,設定一段時間,kettle流程處於等待狀態 |
|
Zip file |
壓縮檔案為ZIP包 |
本文主要閱讀目錄如下:
1、應用場景
這裡簡單概括一下幾種具體的應用場景,按網路環境劃分主要包括:
-
表檢視模式:這種情況我們經常遇到,就是在同一網路環境下,我們對各種資料來源的表資料進行抽取、過濾、清洗等,例如歷史資料同步、異構系統資料互動、資料對稱釋出或備份等都歸屬於這個模式;傳統的實現方式一般都要進行研發(一小部分例如兩個相同表結構的表之間的資料同步,如果sqlserver資料庫可以通過釋出/訂閱實現),涉及到一些複雜的一些業務邏輯如果我們研發出來還容易出各種bug;
-
前置機模式:這是一種典型的資料交換應用場景,資料交換的雙方A和B網路不通,但是A和B都可以和前置機C連線,一般的情況是雙方約定好前置機的資料結構,這個結構跟A和B的資料結構基本上是不一致的,這樣我們就需要把應用上的資料按照資料標準推送到前置機上,這個研發工作量還是比較大的;
-
檔案模式: 資料互動的雙方A和B是完全的物理隔離,這樣就只能通過以檔案的方式來進行資料互動了,例如XML格式,在應用A中我們開發一個介面用來生成標準格式的XML,然後用優盤或者別的介質在某一時間把XML資料拷貝之後,然後接入到應用B上,應用B上在按照標準介面解析相應的檔案把資料接收過來;
綜上3種模式如果我們都用傳統的模式無疑工作量是巨大的,那麼怎麼做才能更高效更節省時間又不容易出錯呢?答案是我們可以用一下Kettle-_-!
2、DEMO實戰
2、1 例項1:資料庫TestA中的UserA表到資料庫TestB的UserB表
1)為方便演示,我這邊把Sql指令碼貼出來,大家直接複製在sqlserver中執行即可,sql指令碼如下:
簡單表之間交換2)Kettle實現方式
功能簡述:資料庫TestA中的UserA表到資料庫TestB的UserB表;
實現流程:建立一個轉換和一個作業Job;
A:建立一個轉換:開啟Kettle.exe,選擇沒有資源庫,進入主介面,新建一個轉換,轉換的字尾名為ktr,轉換建立的步驟如下:
步驟1:建立DB連線,選擇新建DB連線,如下圖,我們輸入相應的Sqlserver配置資訊之後點選Test按鈕測試是否配置正確!
我們需要建立兩個DB連線,分別為TestA和TestB;
步驟2:建立步驟和步驟關係,點選核心物件,我們從步驟樹中選擇【表輸入】,如下圖,這樣拖拽一個表輸入之後,我們雙擊表輸入之後,我們自己可以隨意寫一個sql語句,這個語句表示可以在這個庫中隨意組合,只要sql語句沒有錯誤即可,我這裡只是最簡單的把TestA中的所有資料查出來,語句為select * from usersA。
接下來我們建立另外一個步驟【插入/ 更新】,然後在【表輸入】上同時按住shift鍵和滑鼠左鍵滑向【插入/ 更新】,這樣建立兩個步驟之間的連線,【插入/ 更新】執行的邏輯是如果UserA表中的記錄在UserB中不存在那麼就插入,如果存在就更新,如下圖,在插入更新中我們可以做一些關鍵條件和欄位對映,這裡我們是最簡單的!點選儲存,把我們建立的轉換儲存一下。
建立好轉換之後,我們可以直接執行這個轉換,檢查一下是否有錯,如圖,有錯誤都會在下面的控制檯上輸出。
B:如果我們需要讓這個轉換定時執行怎麼辦呢,那麼我們需要建立一個作業job,見下圖,在簡單表同步這個轉換中,我們把在A步驟中建立的ktl配置上,注意路徑的正確性;
這樣我們在【Start】步驟上面雙擊,如圖:
這樣這個作業就制定好了,點選儲存之後,我們就可以在圖形化介面上點選開始執行了!
2、2 例項2:全面進階的一個稍微複雜的例子
根據客戶,帳戶,交易表中的資料,生成對應的資料檔案,將資料檔案可以匯入到對應表中,並且可以用job來呼叫整個流程。 目標: 1),提交對應的Kettle檔案 2),Kettle流程可以正確執行,不報錯 3),對應的資料檔案生成並格式無誤,對應表中有資料並格式無誤 說明: 源表:資料庫etltest中存在3張表: 目標表:etltest中一張表 Kettle具體解決方式,步驟比較繁瑣,大家可以直接到下載中下載Demo資料庫檔案和ktr、kjb來實戰測試,這樣是最好的,下面的操作僅供參考,轉換預覽圖如下:操作步驟:
在EtltestTrans頁面下,點選左側的【Core Objects】,點選【Input】,選中【表
輸入】,拖動到主視窗釋放滑鼠。
雙擊【表輸入】圖示
資料庫連線選擇剛剛建立好的etltest資料庫連線,在主視窗寫入對應的查詢
語句
Select * from trade ,如下圖:
點選確定完成。
點選左側的【Lookup】,選中【資料庫查詢】,拖動到主視窗釋放滑鼠。
按住shift鍵,用滑鼠點中剛才建立的【表輸入】,拖動到【資料庫查詢】上,
則建立了兩個環節之間的連線,如圖:
雙擊【資料庫查詢】
步驟名稱寫入account 表查詢,資料庫連線選擇剛剛建立好的etltest 資料庫
連線,查詢的表寫入account,查詢所需的關鍵字中,表字段寫入acctno,比較
操作符寫入“=”,欄位1寫入acctno。
在查詢表返回的值裡面寫入custno,確定完成,如下圖:
同上,再建立一個數據庫查詢,命名為cust表查詢,查詢的表寫入cust,查
詢所需的關鍵字寫入custno=custno,查詢表返回的值寫入custname,custid,
custtype,如下圖:
點選左側的【Transform】,選中【過濾記錄】,拖動到主視窗釋放滑鼠。
點選左側的【Scripting】,選中兩個【Modified Java Script Value】,拖動到主窗
口釋放滑鼠。分別雙擊開啟,重新命名為“對公型別修改”和“對私型別修改”。
同時,分別建立【過濾記錄】和【對公型別修改】,【對私型別修改】的連線。
雙擊【規律記錄】開啟。
第一個<field>裡面選擇custtype,點選<value>,在Enter value 裡面寫入1,
確定,如圖:
在傳送true資料給步驟裡,選擇【對私型別修改】,在傳送false資料給步驟
裡,選擇【對公型別修改】,確定儲存,如圖:
雙擊【對公型別修改】,在裡面寫入javascript 指令碼語句
var custtype_cn='對公客戶交易'
在欄位中寫入custtype_cn,型別選為string。確定。
同理,在【對私型別修改】中,在裡面寫入javascript指令碼語句
var custtype_cn='對私客戶交易'
在欄位中寫入custtype_cn,型別選為string。確定。
點選左側的【Transform】,選中兩個【增加常量】,拖動到主視窗釋放滑鼠。
分別雙擊開啟,重新命名為“增加對公常量”和“增加對私常量”。
分別建立【對公型別修改】和【對私型別修改】與【增加對公常量】和【增
加對私常量】的連線,如圖:
雙擊【增加對公常量】,名稱寫入value,型別選擇string,值寫入“這是一
筆對公客戶發生的交易”,確定儲存。
同理,雙擊【增加對私常量】,名稱寫入value,型別選擇string,值寫入“這
是一筆對私客戶發生的交易”,確定儲存。
點選左側的【Output】,選中【文字檔案輸出】,拖動到主視窗釋放滑鼠。
建立【增加對公常量】,【增加對私常量】和【文字檔案輸出】的連線,如圖:
雙擊開啟【文字檔案輸出】,檔名稱寫入D:\etltest\etltest.txt
點選內容標籤,根據情況進行修改,例如
點選欄位標籤
名稱依次寫入tradeid,acctno,amt,custno,custname,custid,custtype_cn,
value,型別根據各個欄位實際型別進行選擇
確定儲存
點選儲存建立好的transformation。
點選執行這個轉換。
點選launch,開始執行
當所有狀態都變已完成時,則轉換完成,如圖:
3、Demo下載
本文主要閱讀目錄如下:
4、Windows任務設定
1、簡介Kettle的Kitchen和Span
前面兩篇文章中主要講述了Kettle的 Spoon的轉換和作業的GUI設計方式以及執行,也給出了Demo實戰,那麼實際上我們的應用模式可能會要求在伺服器上以後臺程序的方式執行這個ETL任務,就像我們傳統上一般都是用Windows服務的方式來處理資料一樣,那麼用Kettle我們怎麼去實現呢?這就需要我們瞭解一下Kettle的Kitchen和Span。
Kitchen——工作(job)執行器 (命令列方式)
Span——轉換(trasform)執行器 (命令列方式)
這裡我們重點講一下 Kitchen.bat作業執行器 ,這個是經常要用到的。
它是一個作業執行引擎,用來執行作業。這是一個命令列執行工具,它的引數說明如下:
-rep : Repository name 任務包所在儲存名
-user : Repository username 執行人
-pass : Repository password 執行人密碼
-job : The name of the job to launch 任務包名稱
-dir : The directory (don''t forget the leading / or \)
-file : The filename (Job XML) to launch
-level : The logging level (Basic, Detailed, Debug, Rowlevel, Error, Nothing) 指定日誌級別
-log : The logging file to write to 指定日誌檔案
-listdir : List the directories in the repository 列出指定儲存中的目錄結構。
-listjobs : List the jobs in the specified directory 列出指定目錄下的所有任務
-listrep : List the defined repositories 列出所有的儲存
-norep : Don''t log into the repository 不寫日誌
2、命令列排程任務配置方式
還是拿我在前面文章中提到的第一個例子來去講一下具體的配置方式,主要的思路就行首先定位到kettle中Kitchen.bat的根目錄,然後執行kitchen命令;
步驟1:首先我們建立一個bat檔案,然後點選編輯進入之後,如下所示,這是定位到Kitchen.bat的目錄;
E:
cd E:\ETL\pdi-open-3.1.0-826
步驟2:執行kitchen命令,如下:
kitchen /file:E:\ETL\指令碼檔案\MyTest.kjb /level:Basic>>D:\MyTest.log
這裡注意配正確路徑,然後後面是一個基本的日誌模式,後面也需要配置日誌的輸出路徑;
3、後臺程序配置執行方式
前面我們已經把bat檔案建立起來了,這時候我們可以以bat方式執行我們的ETL任務了,不過它的問題是伺服器桌面上永遠有個黑CMD螢幕,而且不能關,怎麼讓Bat在螢幕上消失而後臺還能執行呢?具體方法有很多種這裡介紹兩種:
方法一
bat裡有隱藏視窗的命令,很簡單,只需要在程式碼頭部加一段程式碼就可以了。
@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("%~nx0 h",0)(window.close)&&exit
:begin
::下面是你自己的程式碼。
方法二
在你批處理的相同目錄下新建一個記事本,裡面輸入:
DIM objShell set objShell=wscript.createObject("wscript.shell")
iReturn=objShell.Run("cmd.exe /C c:\1.bat", 0, TRUE)
(其中win.bat為你自己的批處理名字,自己改)
然後把這個記事本儲存為字尾名為.vbe的檔案,到時候你只要執行這個vbe檔案就達到目的了!
可以寫的簡單點:
Set ws = CreateObject("Wscript.Shell")
ws.run "cmd /c c:\1.bat",0
或者
CreateObject("WScript.Shell").Run "cmd /c c:\1.bat",0
(這種寫法很多殺軟報毒, 需要替換引數0)
最後那個0是指視窗引數,用法為:
0 隱藏視窗並激活另一視窗。
1 啟用並顯示一個視窗。若視窗是最小化或最大化,則恢復到其原來的大小和位置。
2 啟用視窗並以最小化顯示該視窗。
3 啟用視窗並以最大化顯示該視窗。
4 按視窗最近的大小和位置顯示。活動視窗保持活動。
5 以當前大小和位置啟用並顯示視窗。
6 最小化指定視窗並激活按 Z 序排序的下一個頂層視窗。
7 最小化顯示視窗。活動視窗保持活動。
8 以當前狀態顯示視窗。活動視窗保持活動。
9 啟用並顯示視窗。若視窗是最小化或最大化,則恢復到原來的大小和位置。在還原應用程式的最小化視窗時,應指定該標誌。
4、Windows任務設定
經過前面的兩步,我們已經可以讓ETL作業在伺服器上無聲無息的運行了,但是如何自由排程呢,我們再結合windows的任務計劃即可,這裡不再贅述!
5、Demo下載