版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
-.z.Kettle培訓(xùn)技術(shù)文檔0507Etl介紹ETL〔E*tract-Transform-Load的縮寫,即數(shù)據(jù)抽取、轉(zhuǎn)換、裝載的過程〕,對(duì)于金融IT來說,經(jīng)常會(huì)遇到大數(shù)據(jù)量的處理,轉(zhuǎn)換,遷移,所以了解并掌握一種etl工具的使用,必不可少。Kettle是一款國(guó)外開源的etl工具,純java編寫,綠色無需安裝,數(shù)據(jù)抽取高效穩(wěn)定。Kettle中有兩種腳本文件,transformation和job,transformation完成針對(duì)數(shù)據(jù)的根底轉(zhuǎn)換,job則完成整個(gè)工作流的控制。kettle部署運(yùn)行將kettle文件夾拷貝到本地路徑,例如D盤根目錄。雙擊運(yùn)行kettle文件夾下的spoon.bat文件,出現(xiàn)kettle歡送界面:稍等幾秒選擇沒有資源庫(kù),翻開kettle主界面創(chuàng)立transformation,job點(diǎn)擊頁(yè)面左上角的創(chuàng)立一個(gè)新的transformation,點(diǎn)擊保存到本地路徑,例如保存到D:/etltest下,保存文件名為EtltestTrans,kettle默認(rèn)transformation文件保存后后綴名為ktr點(diǎn)擊頁(yè)面左上角的創(chuàng)立一個(gè)新的job,點(diǎn)擊保存到本地路徑,例如保存到D:/etltest下,保存文件名為EtltestJob,kettle默認(rèn)job文件保存后后綴名為k創(chuàng)立數(shù)據(jù)庫(kù)連接在transformation頁(yè)面下,點(diǎn)擊左邊的【MainTree】,雙擊【DB連接】,進(jìn)展數(shù)據(jù)庫(kù)連接配置。connectionname自命名連接名稱Connectiontype選擇需要連接的數(shù)據(jù)庫(kù)Methodofaccess選擇連接類型Serverhostname寫入數(shù)據(jù)庫(kù)效勞器的ip地址Databasename寫入數(shù)據(jù)庫(kù)名Portnumber寫入端口號(hào)Username寫入用戶名Password寫入密碼例如如下配置:點(diǎn)擊【test】,如果出現(xiàn)如下提示則說明配置成功點(diǎn)擊關(guān)閉,再點(diǎn)擊確定保存數(shù)據(jù)庫(kù)連接。一個(gè)簡(jiǎn)單的ktr例子目的:將一個(gè)數(shù)據(jù)庫(kù)導(dǎo)入到另一個(gè)數(shù)據(jù)庫(kù)中。操作步驟:創(chuàng)立一個(gè)transformation,命名為etlTestTrans.ktr,創(chuàng)立數(shù)據(jù)庫(kù)連接ods,點(diǎn)擊【Input】,選中【表輸入】,拖到主窗口,釋放鼠標(biāo),雙擊打開如下列圖點(diǎn)擊【Transform】,選中【字段選擇】,拖到主窗口,釋放鼠標(biāo)點(diǎn)擊【Output】,選中【表輸出】,拖到主窗口,釋放鼠標(biāo)建立【文本文件輸入】和【字段選擇】與【字段選擇】和【表輸出】的連接雙擊【表輸出】,目標(biāo)表中寫入ZT_TEST_KETTLE,,確定保存雙擊【字段選擇】,點(diǎn)擊獲取選擇的字段,再點(diǎn)擊EdltMapping,點(diǎn)擊OK確定,編輯所有字段對(duì)應(yīng)關(guān)系,點(diǎn)確定。點(diǎn)擊運(yùn)行這個(gè)轉(zhuǎn)換。,則將上一個(gè)ktr中生成的文本,導(dǎo)入到數(shù)據(jù)庫(kù)當(dāng)中。一個(gè)簡(jiǎn)單的k例子目的:將上一個(gè)transformation在一個(gè)job里面調(diào)用執(zhí)行。操作步驟:在etlTestJob頁(yè)面,點(diǎn)擊【CoreObjects】,點(diǎn)擊【Jobentries】,選中【START】拖動(dòng)到主窗口釋放鼠標(biāo),再選中【Transformation】,拖動(dòng)到主窗口釋放鼠標(biāo),建立【START】和【Transformation】之間的連接。雙擊【Transformation】,在Transformationfilename中寫入E:\kettleWorkspace\etlTestTrans.ktr,確定保存。點(diǎn)擊保存創(chuàng)立好的job。點(diǎn)擊運(yùn)行這個(gè)轉(zhuǎn)換。待所有任務(wù)都顯示成功,則為job調(diào)用transformation運(yùn)行成功。一個(gè)增量的例子增量更新按照數(shù)據(jù)種類的不同大概可以分成:
1.
只增加,不更新,
2.
只更新,不增加
3.
即增加也更新
4.
有刪除,有增加,有更新下面針對(duì)前三種做一個(gè)增量的ETL抽取。過程如下:根據(jù)前面講解的例子一樣,首先建立源表〔fina_test1〕和目標(biāo)表〔fina_test2〕,整個(gè)設(shè)計(jì)流程如下:其中第一個(gè)步驟〔輸入-目標(biāo)表〕的sql大概如下模式:selectifnull(ma*(date_seal),'1900-01-0100:00:00')fromfina_test2你會(huì)注意到第二個(gè)步驟和第一個(gè)步驟的連接是黃色的線,這是因?yàn)榈诙€(gè)tableinput〔輸入-源表〕步驟把前面一個(gè)步驟的輸出當(dāng)作一個(gè)參數(shù)來用,所有Kettle用黃色的線來表示,第二個(gè)tableinput〔輸入-源表〕的sql模式大概如下:SELECT*FROMfina_test1wheredate_seal>"后面的一個(gè)問號(hào)就是表示它需要承受一個(gè)參數(shù),你在這個(gè)tableinput〔輸入-源表〕下面需要指定replacevariableinscript選項(xiàng)和執(zhí)行每一行為選中狀態(tài),這樣,Kettle就會(huì)循環(huán)執(zhí)行這個(gè)sql,執(zhí)行的次數(shù)為前面參數(shù)步驟傳入的數(shù)據(jù)集的大小。
關(guān)于第三個(gè)步驟執(zhí)行插入/更新步驟需要特別解釋一下,Kettle執(zhí)行這個(gè)步驟是需要兩個(gè)數(shù)據(jù)流比照,其中一個(gè)是目標(biāo)數(shù)據(jù)庫(kù),你在目標(biāo)表里面指定的,它放在用來查詢的關(guān)鍵字左邊的表字段里面的,另外一個(gè)數(shù)據(jù)流就是你在前一個(gè)步驟傳進(jìn)來的,它放在用來查詢的關(guān)鍵字的右邊,Kettle首先用你傳進(jìn)來的key在數(shù)據(jù)庫(kù)中查詢這些記錄,如果沒有找到,它就插入一條記錄,所有的值都跟你原來的值一樣,如果根據(jù)這個(gè)key找到了這條記錄,kettle會(huì)比擬這兩條記錄,根據(jù)你指定updatefield來比擬,如果數(shù)據(jù)完全一樣,kettle就什么都不做,如果記錄不完全一樣,kettle就執(zhí)行一個(gè)update步驟。備注:主鍵被修改得數(shù)據(jù)認(rèn)為是新記錄刪除的數(shù)據(jù)由在倉(cāng)庫(kù)中需要保存無需考慮然后點(diǎn)擊新建-job,然后job的核心對(duì)象jobentries拉出組建,進(jìn)展執(zhí)行抽取。創(chuàng)立kettle資料庫(kù)資源庫(kù)是用來保存轉(zhuǎn)換任務(wù)的,用戶通過圖形界面創(chuàng)立的的轉(zhuǎn)換任務(wù)可以保存在資源庫(kù)中。資源庫(kù)可以是各種常見的數(shù)據(jù)庫(kù),用戶通過用戶名/密碼來訪問資源庫(kù)中的資源,默認(rèn)的用戶名/密碼是admin/admin資源庫(kù)并不是必須的,如果沒有資源庫(kù),用戶還可以把轉(zhuǎn)換任務(wù)保存在*ml文件中。如果用戶需要?jiǎng)?chuàng)立一個(gè)資源庫(kù),在資源庫(kù)的登錄窗口〔PDI啟動(dòng)時(shí)的第一個(gè)窗口〕中有【新建】按鈕,點(diǎn)擊該按鈕彈出新建資源庫(kù)窗口,在該窗口中選擇一個(gè)數(shù)據(jù)庫(kù)連接,如果沒有事先定義的數(shù)據(jù)庫(kù)連接,則還要點(diǎn)擊【新建】按鈕,來創(chuàng)立一個(gè)數(shù)據(jù)庫(kù)連接。選擇數(shù)據(jù)庫(kù)連接后,要為該資源庫(kù)命名,作為這個(gè)資源庫(kù)的唯一標(biāo)志,最后選擇【創(chuàng)立或更新】按鈕來創(chuàng)立這個(gè)資源庫(kù)。資源庫(kù)可以使多用戶共享轉(zhuǎn)換任務(wù),轉(zhuǎn)換任務(wù)在資源庫(kù)中是以文件夾形式分組管理的,用戶可以自定義文件夾名稱。如何使用kettle讀取包含多行表的E*cel文件如果E*cel工作表的表頭只有一行,使用Kettle讀取這樣的文件是很容易的.
如果E*cel工作表的表頭是多行的,或者是分級(jí)的就需要在容標(biāo)簽下正確設(shè)置列名所占行數(shù)才可以讀取.考慮這樣的一個(gè)工作表如果想把里面的12列數(shù)據(jù)都讀出來,就要考慮如何處理多級(jí)表頭.步驟設(shè)置的詳細(xì)描述:步驟一選擇文件名,現(xiàn)在文件或目錄里到所要添加的e*cel文檔,然后點(diǎn)擊,確定后,點(diǎn)擊,
步驟二選擇要讀取的工作表名稱和要讀取的容在工作表里的起始位置,也就是表頭開場(chǎng)的行號(hào)和列號(hào)(這里行號(hào)和列號(hào)是以0開場(chǎng)的)步驟三設(shè)置要讀取的容的一些屬性,這里要設(shè)置表頭的所占行數(shù)是4行.步驟四錯(cuò)誤處理,選擇如果有錯(cuò)誤終止還是繼續(xù),錯(cuò)誤信息保存的文件等.(圖略)
步驟五選擇字段,如果前面的三個(gè)步驟(不包括錯(cuò)誤處理步驟)都設(shè)置正確,在這個(gè)頁(yè)面選擇"獲取字段"字段按鈕,就會(huì)獲得所有的列名稱和數(shù)據(jù)類型.
這里我們可以看到:多級(jí)表頭中各級(jí)表頭的名稱被疊加起來,形成了唯一的列名.點(diǎn)擊[預(yù)覽]按鈕可以預(yù)覽到數(shù)據(jù)對(duì)于表頭跨連續(xù)的多行,但不分級(jí)的情況也可以使用上述方式處理.kettle注釋:kettle的控制流可以設(shè)置一些簡(jiǎn)單的時(shí)間,并且可以實(shí)現(xiàn)隔斷天、周、月〔三個(gè)只能選一個(gè),不能選那個(gè)月的那周那日〕,但是kettle工具不能關(guān),如果關(guān)了,必須重新啟動(dòng)。kettle里面缺少一個(gè)編輯的字段的插件,導(dǎo)致字段編輯很麻煩,這只能先sql中進(jìn)展手寫,這個(gè)對(duì)寫sql的要求很高。一個(gè)kettle字段轉(zhuǎn)換〔截取〕的例子大致的流程是:表輸入還是正常的sql查詢,沒有添加參數(shù)。字段轉(zhuǎn)換〔截取〕是在進(jìn)展修改。具體樣式如下:具體的用法:transformFunctions里面包括了字符、數(shù)字的一些函數(shù)方法,這些函數(shù)方法可以解決一些字段需要轉(zhuǎn)化的問題。Inputfields和Outputfields里面包括了從表輸入進(jìn)來的字段〔數(shù)據(jù)〕。字段主要轉(zhuǎn)化的操作界面:注意下:substr(***,1,2)中的1代表是第一位開場(chǎng),2代表是取2位,在這里面還可以添加if等語(yǔ)句,進(jìn)展編寫。在字段選擇那里面要配置從js過來的字段,點(diǎn)擊列映射〔前提是已經(jīng)和表輸出連接上〕,這個(gè)字段對(duì)應(yīng)要根據(jù)你實(shí)際從js倒過來的字段和目標(biāo)表相對(duì)應(yīng)的字段一一對(duì)應(yīng)。開源ETL工具kettle系列之常見問題摘要:本文主要介紹使用kettle設(shè)計(jì)一些ETL任務(wù)時(shí)一些常見問題,這些問題大局部都不在官方FAQ上,你可以在kettle的論壇上找到一些問題的答案1.
Join
我得到A數(shù)據(jù)流〔不管是基于文件或數(shù)據(jù)庫(kù)〕,A包含field1,field2,field3字段,然后我還有一個(gè)B數(shù)據(jù)流,B包含field4,field5,field6,我現(xiàn)在想把它們‘加’起來,應(yīng)該怎么樣做.
這是新手最容易犯錯(cuò)的一個(gè)地方,A數(shù)據(jù)流跟B數(shù)據(jù)流能夠Join,肯定是它們包含joinkey,joinkey可以是一個(gè)字段也可以是多個(gè)字段。如果兩個(gè)數(shù)據(jù)流沒有joinkey,則它們就是在做笛卡爾積,一般很少會(huì)這樣。比方你現(xiàn)在需要列出一個(gè)員工的和他所在部門的,如果這是在同一個(gè)數(shù)據(jù)庫(kù),大家都知道會(huì)在一個(gè)sql里面加上where限定條件,但是如果員工表和部門表在兩個(gè)不同的數(shù)據(jù)流里面,尤其是數(shù)據(jù)源的來源是多個(gè)數(shù)據(jù)庫(kù)的情況,我們一般是要使用DatabaseJoin操作,然后用兩個(gè)databasetableinput來表示輸入流,一個(gè)輸入是部門表的,另一個(gè)是員工表的,然后我們認(rèn)為這兩個(gè)表就可以〞Join〞了,我們需要的輸出確實(shí)是這兩個(gè)字段,但是這兩個(gè)字段的輸出并不代表只需要這兩個(gè)字段的輸入,它們之間肯定是需要一個(gè)約束關(guān)系存在的。另外,無論是在做Join,Merge,Update,Delete這些常規(guī)操作的時(shí)候,都是先需要做一個(gè)pare操作的,這個(gè)pare操作都是針對(duì)parekey的,無論兩個(gè)表構(gòu)造是不是一樣的,比方employee表和department表,它們比擬的依據(jù)就是employee的外鍵department_id,沒有這個(gè)parekey這兩個(gè)表是不可能連接的起來的..對(duì)于兩個(gè)表可能還有人知道是直接sql來做連接,如果是多個(gè)輸入數(shù)據(jù)源,然后是三個(gè)表,有人就開場(chǎng)迷茫了,A表一個(gè)字段,B表一個(gè)字段,C表一個(gè)字段,然后就連Join操作都沒有,直接databasetableoutput,然后開場(chǎng)報(bào)錯(cuò),報(bào)完錯(cuò)就到處找高手問,他們的數(shù)據(jù)庫(kù)原理教師已經(jīng)在吐血了。如果是三個(gè)表連接,一個(gè)sql不能搞定,就需要先兩個(gè)表兩個(gè)表的連接,通過兩次parekey連接之后得到你的輸出,記住,你的輸出并不能代表你的輸入.下面總結(jié)一下:
1.
單數(shù)據(jù)源輸入,直接用sql做連接
2.
多數(shù)據(jù)源輸入,〔可能是文本或是兩個(gè)以上源數(shù)據(jù)庫(kù)〕,用databasejoin操作.
3.
三個(gè)表以上的多字段輸出.2.
Kettle的數(shù)據(jù)庫(kù)連接模式
Kettle的數(shù)據(jù)庫(kù)連接是一個(gè)步驟里面控制一個(gè)單數(shù)據(jù)庫(kù)連接,所以kettle的連接有數(shù)據(jù)庫(kù)連接池,你可以在指定的數(shù)據(jù)庫(kù)連接里面指定一開場(chǎng)連接池里面放多少個(gè)數(shù)據(jù)庫(kù)連接,在創(chuàng)立數(shù)據(jù)庫(kù)連接的時(shí)候就有Pooling選項(xiàng)卡,里面可以指定最接數(shù)和初始連接數(shù),這可以一定程度上提高速度.3.
transaction
我想在步驟A執(zhí)行一個(gè)操作〔更新或者插入〕,然后在經(jīng)過假設(shè)干個(gè)步驟之后,如果我發(fā)現(xiàn)*一個(gè)條件成立,我就提交所有的操作,如果失敗,我就回滾,kettle提供這種事務(wù)性的操作嗎?
Kettle里面是沒有所謂事務(wù)的概念的,每個(gè)步驟都是自己管理自己的連接的,在這個(gè)步驟開場(chǎng)的時(shí)候翻開數(shù)據(jù)庫(kù)連接,在完畢的時(shí)候關(guān)閉數(shù)據(jù)庫(kù)連接,一個(gè)步驟是肯定不會(huì)跨session的〔數(shù)據(jù)庫(kù)里面的session〕,另外,由于kettle是并行執(zhí)行的,所以不可能把一個(gè)數(shù)據(jù)庫(kù)連接翻開很長(zhǎng)時(shí)間不放,這樣可能會(huì)造成鎖出現(xiàn),雖然不一定是死鎖,但是對(duì)性能還是影響太大了。ETL中的事務(wù)對(duì)性能影響也很大,所以不應(yīng)該設(shè)計(jì)一種依賴與事務(wù)方式的ETL執(zhí)行順序,畢竟這不是OLTP,因?yàn)槟憧赡芤淮涡枰峤坏臄?shù)據(jù)量是幾百GB都有可能,任何一種數(shù)據(jù)庫(kù)維持一個(gè)幾百GB的回滾段性能都是會(huì)不大幅下降的.4.
我真的需要transaction但又不想要一個(gè)很復(fù)雜的設(shè)計(jì),能不能提供一個(gè)簡(jiǎn)單一點(diǎn)的方式
Kettle在GA版中將推出一種新功能,在一個(gè)tableoutput步驟中有一個(gè)Miscellaneous選項(xiàng)卡,其中有一個(gè)Useuniqueconnections的選項(xiàng),如果你選中的話就可以得到一個(gè)transaction的簡(jiǎn)單版,
由于是使用的單數(shù)據(jù)庫(kù)連接,所以可以有錯(cuò)誤的時(shí)候回滾事務(wù),不過要提醒一點(diǎn)是這種方式是以犧牲非常大的性能為前提條件的,對(duì)于太大的數(shù)據(jù)量是不適合的(個(gè)人仍然不建議使用這種方式)5.
temporary表如何使用
我要在ETL過程中創(chuàng)立一個(gè)中間表,當(dāng)*個(gè)條件成立的時(shí)候,我要把中間表的數(shù)據(jù)進(jìn)展轉(zhuǎn)換,當(dāng)另一條件成立的時(shí)候我要對(duì)中間表進(jìn)展另一個(gè)操作,我想使用數(shù)據(jù)庫(kù)的臨時(shí)表來操作,應(yīng)該用什么步驟。
首先從temp表的生命周期來分,temp分為事務(wù)臨時(shí)表和會(huì)話臨時(shí)表,前面已經(jīng)解釋過了,kettle是沒有所謂事務(wù)的概念的,所以自然也沒有所謂的事務(wù)臨時(shí)表。Kettle的每個(gè)步驟管理自己的數(shù)據(jù)庫(kù)連接,連接一完畢,kettle也就自然丟掉了這個(gè)連接的session的handler,沒有方法可以在其他步驟拿回這個(gè)session的handler,所以也就不能使用所謂的會(huì)話臨時(shí)表,當(dāng)你嘗試再開一個(gè)連接的時(shí)候,你可以連上這個(gè)臨時(shí)表,但是你想要的臨時(shí)表里面的數(shù)據(jù)都已經(jīng)是空的(數(shù)據(jù)不一定被去除了,但是你連不上了),所以不要設(shè)計(jì)一個(gè)需要使用臨時(shí)表的轉(zhuǎn)換
之所以會(huì)使用臨時(shí)表,其實(shí)跟需要〞事務(wù)〞特性有一點(diǎn)類似,都是希望在ETL過程中提供一種緩沖。臨時(shí)表很多時(shí)候都不是*一個(gè)源表的全部數(shù)據(jù)的鏡像,很多時(shí)候臨時(shí)表都是很小一局部結(jié)果集,可能經(jīng)過了*種計(jì)算過程,你需要臨時(shí)表無非是基于下面三個(gè)特性:
1.
表構(gòu)造固定,用一個(gè)固定的表來承受一局部數(shù)據(jù)。
2.
每次連接的時(shí)候里面沒有數(shù)據(jù)。你希望它承受數(shù)據(jù),但是不保存,每次都好似執(zhí)行了truncatetable操作一樣
3.
不同的時(shí)候連接臨時(shí)表用同一個(gè)名字,你不想使用多個(gè)連接的時(shí)候用類似與temp1,temp2,temp3,temp4這種名字,應(yīng)為它們表構(gòu)造一樣。
既然臨時(shí)表不能用,應(yīng)該如何設(shè)計(jì)ETL過程呢?〔可以用*種詭異的操作搞出臨時(shí)表,不過不建議這樣做罷了〕
如果你的ETL過程比擬的單線程性,也就是你清楚的知道同一時(shí)間只有一個(gè)這樣的表需要,你可以創(chuàng)立一個(gè)普通的表,每次連接的時(shí)候都執(zhí)行truncate操作,不管是通過tableoutput的truncatetable選項(xiàng),還是通過手工執(zhí)行truncatetablesql語(yǔ)句〔在e*ecutesqlscript步驟〕都可以到達(dá)目的〔基于上面的1,2特性〕
如果你的ETL操作比擬的多線程性,同一時(shí)間可能需要多個(gè)表構(gòu)造一樣并且里面都是為空的表〔基于上面1,2,3特性〕,你可以創(chuàng)立一個(gè)“字符串+序列〞
的模式,每次需要的時(shí)候,就創(chuàng)立這樣的表,用完之后就刪除,因?yàn)槟阕约翰灰欢ㄖ滥阈枰嗌賯€(gè)這種類型的表,所以刪除會(huì)比truncate好一些。
下面舉個(gè)例子怎么創(chuàng)立這種表:
你可以使用*種約定的表名比方department_temp作為department的臨時(shí)表?;蛘?/p>
把a(bǔ)rgument傳到表名,使用department_${argument}的語(yǔ)法,
如果你需要多個(gè)這種表,使用一個(gè)sequence操作+e*ecutesqlscript操作,e*ecutesqlscript就下面這種模式
Createtable_"
(…………..)
在表的名字上加參數(shù),前面承受一個(gè)sequence或類似的輸入操作.
需要注意的是這種參數(shù)表名包括databasetableinput或者e*ecutesqlscript,只要是參數(shù)作為表名的情況前面的輸入不能是從數(shù)據(jù)庫(kù)來的,應(yīng)為沒有方法執(zhí)行這種preparedStatement
語(yǔ)句,從數(shù)據(jù)庫(kù)來的值后面的操作是“值操作〞,而不是字符串替換,只有argument或者sequence操作當(dāng)作參數(shù)才是字符串替換.(這一點(diǎn)官方FAQ也有提到)6.
updatetable和e*ecutesqlscript里面執(zhí)行update的區(qū)別
執(zhí)行updatetable操作是比擬慢的,它會(huì)一條一條基于parekey比照數(shù)據(jù),然后決定是不是要執(zhí)行updatesql,如果你知道你要怎么更新數(shù)據(jù)盡可能的使用e*ecutesqlscript操作,在里面手寫updatesql〔注意源數(shù)據(jù)庫(kù)和目標(biāo)數(shù)據(jù)庫(kù)在哪〕,這種多行執(zhí)行方式〔updatesql〕肯定比單行執(zhí)行方式〔updatetable操作〕快的多。
另一個(gè)區(qū)別是e*ecutesqlscript操作是可以承受參數(shù)的輸入的。它前面可以是一個(gè)跟它完全不關(guān)的表一個(gè)sql:
selectfield1,field2field3fromtableA
后面執(zhí)行另一個(gè)表的更新操作:
updatetableBsetfield4="wherefield5="Andfield6="
然后選中e*ecutesqlscript的e*ecuteforeachrow.注意參數(shù)是一一對(duì)應(yīng)的.(field4對(duì)應(yīng)field1的值,
field5對(duì)應(yīng)field2的值,field6對(duì)應(yīng)field3的值)7.
kettle的性能
kettle本身的性能絕對(duì)是能夠應(yīng)對(duì)大型應(yīng)用的,一般的基于平均行長(zhǎng)150的一條記錄,假設(shè)源數(shù)據(jù)庫(kù),目標(biāo)數(shù)據(jù)庫(kù)以及kettle都分別在幾臺(tái)機(jī)器上〔最常見的桌面工作模式,雙核,1G存〕,速度大概都可以到5000行每秒左右,如果把硬件提高一些,性能還可以提升,但是ETL過程中難免遇到性能問題,下面一些通用的步驟也許能給你一些幫助.
盡量使用數(shù)據(jù)庫(kù)連接池
盡量提高批處理的mitsize
盡量使用緩存,緩存盡量大一些〔主要是文本文件和數(shù)據(jù)流〕
Kettle是Java做的,盡量用大一點(diǎn)的存參數(shù)啟動(dòng)Kettle.
可以使用sql來做的一些操作盡量用sql
Group,merge,streamlookup,splitfield這些操作都是比擬慢的,想方法防止他們.,能用sql就用sql
插入大量數(shù)據(jù)的時(shí)候盡量把索引刪掉
盡量防止使用update,delete操作,尤其是update,如果可以把update變成先delete,
后insert.
能使用truncatetable的時(shí)候,就不要使用deleteallrow這種類似sql
合理的分區(qū)
如果刪除操作是基于*一個(gè)分區(qū)的,就不要使用deleterow這種方式〔不管是deletesql還是delete步驟〕,直接把分區(qū)drop掉,再重新創(chuàng)立
盡量縮小輸入的數(shù)據(jù)集的大小〔增量更新也是為了這個(gè)目的〕
盡量使用數(shù)據(jù)庫(kù)原生的方式裝載文本文件(Oracle的sqlloader,mysql的bulkloader步驟)
盡量不要用kettle的calculate計(jì)算步驟,能用數(shù)據(jù)庫(kù)本身的sql就用sql,不能用sql就盡量想方法用procedure,實(shí)在不行才是calculate步驟.
要知道你的性能瓶頸在哪,可能有時(shí)候你使用了不恰當(dāng)?shù)姆绞剑瑢?dǎo)致整個(gè)操作都變慢,觀察kettlelog生成的方式來了解你的ETL操作最慢的地方。
遠(yuǎn)程數(shù)據(jù)庫(kù)用文件+FTP的方式來傳數(shù)據(jù),文件要壓縮?!仓灰皇蔷钟蚓W(wǎng)都可以認(rèn)為是遠(yuǎn)程連接〕8.
描述物理環(huán)境
源數(shù)據(jù)庫(kù)的操作系統(tǒng),硬件環(huán)境,是單數(shù)據(jù)源還是多數(shù)據(jù)源,數(shù)據(jù)庫(kù)怎么分布的,做ETL的那臺(tái)機(jī)器放在哪,操作系統(tǒng)和硬件環(huán)境是什么,目標(biāo)數(shù)據(jù)倉(cāng)庫(kù)的數(shù)據(jù)庫(kù)是什么,操作系統(tǒng),硬件環(huán)境,數(shù)據(jù)庫(kù)的字符集怎么選,數(shù)據(jù)傳輸方式是什么,開發(fā)環(huán)境,測(cè)試環(huán)境和實(shí)際的生產(chǎn)環(huán)境有什么區(qū)別,是不是需要一個(gè)中間數(shù)據(jù)庫(kù)(staging數(shù)據(jù)庫(kù)),源數(shù)據(jù)庫(kù)的數(shù)據(jù)庫(kù)版本號(hào)是多少,測(cè)試數(shù)據(jù)庫(kù)的版本號(hào)是多少,真正的目標(biāo)數(shù)據(jù)庫(kù)的版本號(hào)是多少…….這些信息也許很零散,但是都需要一份專門的文檔來描述這些信息,無論是你遇到問題需要?jiǎng)e人幫助的時(shí)候描述問題本身,還是發(fā)現(xiàn)測(cè)試環(huán)境跟目標(biāo)數(shù)據(jù)庫(kù)的版本號(hào)不一致,這份專門的文檔都能提供一些根本的信息9.
procedure
為什么我不能觸發(fā)procedure"
這個(gè)問題在官方FAQ里面也有提到,觸發(fā)procedure和client都需要一個(gè)類似與觸發(fā)器的條件,你可以使用generaterow步驟產(chǎn)生一個(gè)空的row,然后把這條記錄連上procedure步驟,這樣就會(huì)使這條沒有記錄的空行觸發(fā)這個(gè)procedure(如果你打算使用無條件的單次觸發(fā)),當(dāng)然procedure也可以象tableinput里面的步驟那樣傳參數(shù)并且屢次執(zhí)行.
另外一個(gè)建議是不要使用復(fù)雜的procedure來完本錢該ETL任務(wù)完成的任務(wù),比方創(chuàng)立表,填充數(shù)據(jù),創(chuàng)立物化視圖等等.10.
字符集
Kettle使用Java通常使用的UTF8來傳輸字符集,所以無論你使用何種數(shù)據(jù)庫(kù),任何數(shù)據(jù)庫(kù)種類的字符集,kettle都是支持的,如果你遇到了字符集問題,也許下面這些提示可以幫助你:
1.
單數(shù)據(jù)庫(kù)到單數(shù)據(jù)庫(kù)是絕對(duì)不會(huì)出現(xiàn)亂碼問題的,不管原數(shù)據(jù)庫(kù)和目標(biāo)數(shù)據(jù)庫(kù)是何種種類,何種字符集
2.
多種不同字符集的原數(shù)據(jù)庫(kù)到一個(gè)目標(biāo)數(shù)據(jù)庫(kù),你首先需要確定多種源數(shù)據(jù)庫(kù)的字符集的最大兼容字符集是什么,如果你不清楚,最好的方法就是使用UTF8來創(chuàng)立數(shù)據(jù)庫(kù).
3.
不要以你工作的環(huán)境來判斷字符集:現(xiàn)在*一個(gè)測(cè)試人員手上有一個(gè)oracle的基于***字符集的已經(jīng)存在的數(shù)據(jù)庫(kù),并且非常不幸的是***字符集不是utf8類型的,于是他把另一個(gè)基于yyy字符集的oracle數(shù)據(jù)庫(kù)要經(jīng)過*一個(gè)ETL過程轉(zhuǎn)換到oracle,后來他發(fā)現(xiàn)無論怎么樣設(shè)置都會(huì)出現(xiàn)亂碼,這是因?yàn)槟愕臄?shù)據(jù)庫(kù)本身的字符集不支持,無論你怎么設(shè)置都是沒用的.測(cè)試的數(shù)據(jù)庫(kù)不代表最后產(chǎn)品運(yùn)行的數(shù)據(jù)庫(kù),尤其是有時(shí)候?yàn)榱耸∈掳讯鄠€(gè)不同的工程的不相關(guān)的數(shù)據(jù)庫(kù)裝在同一臺(tái)機(jī)器上,測(cè)試的時(shí)候又沒有分析清楚這種環(huán)境,所以也再次強(qiáng)調(diào)描述物理環(huán)境的重要性.
4.
你所看到的不一定代表實(shí)際儲(chǔ)存的:mysql處理字符集的時(shí)候是要在jdbc連接的參數(shù)里面加上字符集參數(shù)的,而oracle則是需要效勞器端和客戶端使用同一種字符集才能正確顯示,所以你要明確你所看到的字符集亂碼不一定代表真的就是字符集亂碼,這需要你檢查在轉(zhuǎn)換之前的字符集是否會(huì)出現(xiàn)亂碼和轉(zhuǎn)換之后是否出現(xiàn)亂碼,你的桌面環(huán)境可能需要變動(dòng)一些參數(shù)來適應(yīng)這種變動(dòng)
5.
不要在一個(gè)轉(zhuǎn)換中使用多個(gè)字符集做為數(shù)據(jù)源.11.
預(yù)定義時(shí)間維
Kettle提供了一個(gè)小工具幫助我們預(yù)填充時(shí)間維,這個(gè)工具在kettle_home/samples/transformations/General–populatedatedimension.這個(gè)例如產(chǎn)生的數(shù)據(jù)不一定能滿足各種需要,不過你可以通過修改這個(gè)例如來滿足自己的需求.12.
SQLtab和Optionstab
在你創(chuàng)立一個(gè)數(shù)據(jù)庫(kù)連接的時(shí)候除了可以指定你一次需要初始化的連接池參數(shù)之外〔在Pooling選項(xiàng)卡下面〕,還包括一個(gè)Options選項(xiàng)卡和一個(gè)SQL選項(xiàng)卡,Options選項(xiàng)卡里面主要設(shè)置一些連接時(shí)的參數(shù),比方automit是on還是off,defaultFetchSize,useCursorFetch(mysql默認(rèn)支持的),oracle還支持比方defaultE*ecuteBatch,oracle.jdbc.StreamBufferSize,oracle.jdbc.FreeMemoryOnEnterImplicitCache,你可以查閱對(duì)應(yīng)數(shù)據(jù)庫(kù)所支持的連接參數(shù),另外一個(gè)小提示:在創(chuàng)立數(shù)據(jù)庫(kù)連接的時(shí)候,選擇你的數(shù)據(jù)庫(kù)類型,然后選到Options選項(xiàng)卡,下面有一個(gè)Showhelpte*tonoptionsusage,點(diǎn)擊這個(gè)按鈕會(huì)把你帶到對(duì)應(yīng)各個(gè)數(shù)據(jù)庫(kù)的連接參數(shù)的官方的一個(gè)參數(shù)列表頁(yè)面,通過查詢這個(gè)列表頁(yè)面你就可以知道那種數(shù)據(jù)庫(kù)可以使用何種參數(shù)了.
對(duì)于SQL選項(xiàng)卡就是在你一連接這個(gè)Connection之后,Kettle會(huì)立刻執(zhí)行的sql語(yǔ)句,個(gè)人比擬推薦的一個(gè)sql是執(zhí)行把所有日期格式統(tǒng)一成同一格式的sql,比方在oracle里面就是:
altersessionsetnls_date_format=*************
altersessionsetnls_*********=************
這樣可以防止你在轉(zhuǎn)換的時(shí)候大量使用to_date(),to_char函數(shù)而僅僅只是為了統(tǒng)一日期格式,對(duì)于增量更新的時(shí)候尤其適用.13.
數(shù)據(jù)復(fù)制
有的時(shí)候可能我們需要的是類似數(shù)據(jù)復(fù)制或者一個(gè)備份數(shù)據(jù)庫(kù),這個(gè)時(shí)候你需要的是一種數(shù)據(jù)庫(kù)私有的解決方案,Kettle也許并不是你的第一選擇,比方對(duì)于Oracle來說,可能rman,oraclestream,oraclereplication等等,mysql也有mysqlrmaster/slave模式的replication等私有的解決方法,如果你確定你的需求不是數(shù)據(jù)集成這方面的,則也許kettle并不是一個(gè)很好的首選方案,你應(yīng)該咨詢一下專業(yè)的DBA人士也會(huì)會(huì)更好.14.
如何控制版本變更
Kettle的每一個(gè)transformation和job都有一個(gè)version字段〔在你保存的時(shí)候〕,不過這個(gè)功能還不實(shí)用,如果你需要版本控制的話,還是建議你將transformation和job轉(zhuǎn)換成文本文件保存,然后用svn或cvs或任意你熟悉的版本控制系統(tǒng)將其保存,kettle將在下一個(gè)版本參加版本控制的功能〔做的更易用〕.15.
支持的數(shù)據(jù)源
Kettle支持相當(dāng)廣的數(shù)據(jù)源,比方在數(shù)據(jù)庫(kù)里面的一些不太常見的Access,Ma*DB(SAPDB),Hypersonic,SAPR/3system,BorlandInterbase,OracleRDB,Teradata和3.0新參加的SybaseIQ.
另外還包括E*cel,CSV,LDAP,以及OLAPServerMondrian,目前支持WebService不過暫時(shí)還不支持SOAP.16.
調(diào)試和測(cè)試
當(dāng)ETL轉(zhuǎn)換出現(xiàn)不可預(yù)知的問題時(shí),或是你不清楚*個(gè)步驟的功能是什么的情況下,你可能需要?jiǎng)?chuàng)立一個(gè)模擬環(huán)境來調(diào)適程序,下面一些建議可能會(huì)有所幫助:
盡量使用generaterow步驟或者固定的一個(gè)文本文件來創(chuàng)立一個(gè)模擬的數(shù)據(jù)源
模擬的數(shù)據(jù)源一定要有代表性,數(shù)據(jù)集一定盡量小〔為了性能考慮〕但是數(shù)據(jù)本身要足夠分散.
創(chuàng)立了模擬的數(shù)據(jù)集后你應(yīng)該清楚的知道你所要轉(zhuǎn)換之后的數(shù)據(jù)時(shí)什么樣的.17.
錯(cuò)誤處理
在ETL任務(wù)中由于數(shù)據(jù)問題出現(xiàn)轉(zhuǎn)換錯(cuò)誤是一件非常正常的事情,你不應(yīng)該設(shè)計(jì)一個(gè)依賴于臨時(shí)表或者擁有事務(wù)特點(diǎn)的ETL過程,面對(duì)數(shù)據(jù)源質(zhì)量問題的巨大挑戰(zhàn),錯(cuò)誤處理是并不可少的,kettle同樣提供非常方便的錯(cuò)誤處理方式,在你可能會(huì)出錯(cuò)的步驟點(diǎn)擊右鍵選擇DefineErrorhanding,它會(huì)要求你指定一個(gè)處理error的步驟,你可以使用文本文件或者數(shù)據(jù)庫(kù)的表來儲(chǔ)存這些錯(cuò)誤信息,這些錯(cuò)誤信息會(huì)包含一個(gè)id和一個(gè)出錯(cuò)的字段,當(dāng)你得到這些錯(cuò)誤信息之后就需要你自己分析出錯(cuò)的原因了,比方違反主鍵約束可能是你生成主鍵的方式有錯(cuò)誤或者本身的數(shù)據(jù)有重復(fù),而違反外鍵約束則可能是你依賴的一些表里面的數(shù)據(jù)還沒有轉(zhuǎn)換或者外鍵表本身過濾掉了這些數(shù)據(jù).當(dāng)你調(diào)整了這些錯(cuò)誤之后,確定所有依賴的數(shù)據(jù)都被正確的處理了.kettleuserguide里面有更詳細(xì)的解釋,里面還附帶了一個(gè)使用javascript來處理錯(cuò)誤的例如,這種方式可以作為處理簡(jiǎn)單數(shù)據(jù)質(zhì)量的方式.18.
文檔,文檔,文檔
Kettle提供了豐富的文檔和使用手冊(cè),小到一個(gè)數(shù)據(jù)庫(kù)連接怎么連,大到一個(gè)功能怎么實(shí)現(xiàn),所有的參數(shù)列表,對(duì)話框的每一個(gè)輸入輸出代表什么意思都有解釋,所以當(dāng)你遇到問題你應(yīng)該第一時(shí)間翻閱這些文檔,也許上面已經(jīng)告訴你怎么做了.另外kettle還有一個(gè)非常活潑的社區(qū),你可以到上面提問,但是記住在你提問之前先搜索一下論壇看有沒有類似的問題已經(jīng)問過了,如果沒有記得描述清楚你的問題總結(jié)
本系列文章主要討論了如何使用kettle來處理數(shù)據(jù)倉(cāng)庫(kù)中的緩慢增長(zhǎng)維,動(dòng)態(tài)ETL如何設(shè)計(jì),增量更新的一些設(shè)計(jì)技巧,在應(yīng)用程序中如何集成kettle以及在使用kettle時(shí)的一些常見問題.如果你正在尋找一個(gè)工具來幫助你解決數(shù)據(jù)庫(kù)的集成問題或是你打算建立一個(gè)商業(yè)智能工程的數(shù)據(jù)倉(cāng)庫(kù),則kettle是一個(gè)不錯(cuò)的選擇,你不用支付任何費(fèi)用就可以得到很多很多數(shù)據(jù)集成的特性,大量文檔和社區(qū)支持.難道這些不就是你希望從一個(gè)商業(yè)工具上的到的嗎?還在等什么,開場(chǎng)你的數(shù)據(jù)集成之旅吧開源ETL工具kettle系列之在應(yīng)用程序中集成摘要:本文主要討論如何在你自己的Java應(yīng)用程序中集成Kettle如果你需要在自己的Java應(yīng)用程序中集成Kettle,一般來說有兩種應(yīng)用需求,一種是通過純?cè)O(shè)計(jì)器來設(shè)計(jì)ETL轉(zhuǎn)換任務(wù),然后保存成*種格式,比方*ml或者在數(shù)據(jù)庫(kù)中都可以,然后自己調(diào)用程序解析這個(gè)格式,執(zhí)行這種轉(zhuǎn)換,是比擬抽象的一種執(zhí)行方式,ETL里面轉(zhuǎn)換了什么東西我們并不關(guān)心,只關(guān)心它有沒有正常執(zhí)行。另一種是通過完全編程的方式來實(shí)現(xiàn),詳細(xì)的控制每一個(gè)步驟,需要知道轉(zhuǎn)換執(zhí)行的成功與否,這種方式可能需要更多的理解kettle的API以便更好的跟你的應(yīng)用程序嚴(yán)密結(jié)合,不過難度也比擬大,可以很好的定制你的應(yīng)用程序,代價(jià)自然是入門門檻比擬高。本文主要向你解釋第一種Kettle的集成方式,文中所列出的代碼節(jié)選自pentaho,不過應(yīng)用程序本身跟pentaho沒有什么關(guān)系。
Pentaho集成kettle的代碼主要是兩個(gè)類,KettleSystemListener和Kettleponent,看名字就猜出KettleSystemListener主要是起監(jiān)聽器的作用,它主要負(fù)責(zé)初始化kettle的一些環(huán)境變量,這個(gè)類主要包含四個(gè)方法:startup(),readProperties(),environmentInit(),shutdown(),程序入口自然是startup()方法,然后它會(huì)調(diào)用environmentInit()方法,這個(gè)方法就調(diào)用readProperties()方法讀一個(gè)配置文件perties,這個(gè)文件主要記錄者kettle運(yùn)行時(shí)可以調(diào)用的一些環(huán)境變量,關(guān)于perties文件怎么用,第二篇文章“使用Kettle設(shè)計(jì)動(dòng)態(tài)轉(zhuǎn)換〞有提到,readProperties〔〕方法讀完這個(gè)文件之后就把里面的鍵值對(duì)轉(zhuǎn)換成變量傳給kettle運(yùn)行環(huán)境.當(dāng)kettle運(yùn)行完了之后就調(diào)用shutdown()方法完畢轉(zhuǎn)換.KettleSystemListener相對(duì)邏輯比擬簡(jiǎn)單,就不多介紹,下面主要介紹重點(diǎn)類:
Kettleponent
Kettleponent的方法主要有三種類型,一類是用來初始化工作,做一些驗(yàn)證工作,第二類是執(zhí)行轉(zhuǎn)換的方法,也是主要需要討論的方法,第三類是取得數(shù)據(jù)結(jié)果的,有時(shí)候你需要得到轉(zhuǎn)換的結(jié)果交給下一個(gè)步驟處理.下面分別討論這三類方法。初始化
Kettleponent的初始化工作主要是驗(yàn)證這個(gè)轉(zhuǎn)換,包括有validateSystemSettings〔〕,init〔〕,validateAction〔〕,全部都是public方法,validateSystemSettings〔〕會(huì)檢查kettle使用何種方式來連接資源庫(kù)。
kettle有兩種方式連接資源庫(kù),一種是純數(shù)據(jù)庫(kù)式,也就是你所有的轉(zhuǎn)換全部都保存在一個(gè)數(shù)據(jù)庫(kù)中,一般你在開場(chǎng)使用kettle的時(shí)候,它都會(huì)要求你建立一個(gè)資源倉(cāng)庫(kù),這個(gè)資源倉(cāng)庫(kù)的連接方式就是你的數(shù)據(jù)庫(kù)連接,你需要能夠有相應(yīng)的數(shù)據(jù)庫(kù)驅(qū)動(dòng)和對(duì)應(yīng)的連接用戶名和密碼。另外一種連接方式是使用文本文件,也就是*ml文件,在做完任何轉(zhuǎn)換之后,我們都可以把轉(zhuǎn)換或者Job變成*ml文件輸出,這個(gè)輸出文件包含你所有轉(zhuǎn)換的全部信息。
在例如應(yīng)用中使用的是文件的連接方式,下面看一下初始化的一段代碼:
BooleanuseRepository=PentahoSystem.getSystemSetting("kettle/settings.*ml",
"repository.type","files").equals("rdbms");
PentahoSystem.getSystemSetting〔〕方法只是返回一個(gè)字符串,使用的*path讀一個(gè)*ml的對(duì)應(yīng)字段,下面列出settings.*ml文件:
<kettle-repository>
<!--Thevalueswithin<properties>arepasseddirectlytotheKettlePentahoponents.-->
<!--ThisisthelocationoftheKettlerepositories.*mlfile,leaveemptyifthedefaultisused:$HOME/.kettle/repositories.*ml-->
<repositories.*ml.file></repositories.*ml.file>
<repository.type>files</repository.type>
<!--
Thenameoftherepositorytouse-->
<></>
<repository.userid>admin</repository.userid>
<repository.password>admin</repository.password>
</kettle-repository>
可以看到其中的repositories.*ml.file上面的一段注釋,如果這個(gè)值為空會(huì)默認(rèn)使用$HOME/.kettle/repository.*ml文件當(dāng)作資源庫(kù)的連接文件,由于例如中使用的是文本文件所以沒有用數(shù)據(jù)庫(kù)連接,下面的repository.userid和repository.password是指的kettle的資源庫(kù)連接的用戶名和密碼,一般默認(rèn)安裝就兩個(gè),admin/admin
和guest/guest,這里的用戶名和密碼不是連接數(shù)據(jù)庫(kù)的用戶名和密碼,連接數(shù)據(jù)庫(kù)的用戶名和密碼是在另外一個(gè)文件repositories.*ml.file指定的值所定義的
一般默認(rèn)的kettle安裝并且運(yùn)行了一段時(shí)間之后,會(huì)在$HOME/.kettle目錄下創(chuàng)立一些文件,如果你要在自己的系統(tǒng)中集成kettle的話,也需要保存這些文件,當(dāng)然不一定位置是在原來的位置,關(guān)鍵是要讓kettle知道這些文件放在哪。執(zhí)行轉(zhuǎn)換
當(dāng)讀完了這些配置文件并且驗(yàn)證了之后,Kettleponent就開場(chǎng)把前面讀到的轉(zhuǎn)換文件或者資源庫(kù)類型變成Kettle的API,這主要是在e*ecuteAction〔〕方法里面進(jìn)展,它當(dāng)然根據(jù)連接方式也分兩種執(zhí)行類型:
1.
文本執(zhí)行方式
2.
資源庫(kù)連接方式文本執(zhí)行方式需要承受一個(gè)你指定的運(yùn)行轉(zhuǎn)換的文件或者Job的文件,然后把這個(gè)*ml文件解析成Kettle能夠執(zhí)行的模式,
根據(jù)執(zhí)行的類型又可以分成兩種:
1.
Trans任務(wù)
2.
Job任務(wù)
兩個(gè)執(zhí)行的邏輯差不多,下面先介紹Trans的執(zhí)行方式:執(zhí)行Trans任務(wù)
transMeta=newTransMeta(fileAddress,repository,true);
transMeta.setFilename(fileAddress);
然后它會(huì)調(diào)用:
e*ecuteTransformation(TransMetatransMeta,LogWriterlogWriter)
這個(gè)方法是真正的把前面的來的transMeta轉(zhuǎn)換成trans對(duì)象,等待下一步的執(zhí)行:
Transtrans=newTrans(logWriter,transMeta);
ListstepList=trans.getSteps();
for(intstepNo=0;stepNo<stepList.size();stepNo++){
StepMetaDatabistep=(StepMetaDatabi)stepList.get(stepNo);
if(step.stepname.equals(stepName)){
①
Rowrow=transMeta.getStepFields(stepName);
//createthemetadatathatthePentahoresultsetneeds
StringfieldNames[]=row.getFieldNames();
Stringcolumns[][]=newString[1][fieldNames.length];
for(intcolumn=0;column<fieldNames.length;column++){
columns[0][column]=fieldNames[column];
}
②
MemoryMetaDatametaData=newMemoryMetaData(columns,null);
results=newMemoryResultSet(metaData);
//addourselfasarowlistener
③
step.step.addRowListener(this);
foundStep=true;
break;
}
}
1.Row對(duì)象是kettle用來表示一行數(shù)據(jù)的標(biāo)準(zhǔn)對(duì)象,跟jdbc取出來的一條數(shù)據(jù)轉(zhuǎn)化后成為的一個(gè)POJO是一樣的。里面可以包含多個(gè)字段。
2.MemoryMetaData對(duì)象是pentaho特有的,是專門用來返回ETL任務(wù)執(zhí)行后的結(jié)果的,與標(biāo)準(zhǔn)的JDBC里面的resultSet對(duì)應(yīng)的resultSetMetaData
是一樣的。
3.對(duì)于如何處理數(shù)據(jù)的一個(gè)Listener,實(shí)現(xiàn)的是一個(gè)RowListener,數(shù)據(jù)是每一行每一行處理的,后面會(huì)介紹如果需要輸出數(shù)據(jù)怎么取得這些輸出數(shù)據(jù)。如果不需要放回任何對(duì)象,則從1處開場(chǎng)都可以不要,只要初始化step對(duì)象即可。所有的step對(duì)象都已經(jīng)初始化之后就可以開場(chǎng)執(zhí)行了,
trans.startThreads();
trans.waitUntilFinished();
完畢之后還有一些清理工作就不列出了。執(zhí)行Job任務(wù)
執(zhí)行Job任務(wù)之前還是會(huì)讀取Job任務(wù)的描述文件,然后把這個(gè)描述文件〔kettle的.ktr文件〕變成一個(gè)*ml文檔的dom:
org.w3c.dom.Documentdoc=*mlW3CHelper.getDomFromString(job*mlStr);
之后也是初始化對(duì)應(yīng)的元數(shù)據(jù)對(duì)象JobMeta
jobMeta=newJobMeta(logWriter,doc.getFirstChild(),repository);
得到了jobMeta之后就可以執(zhí)行這個(gè)Job了,這里跟trans是一樣的。
job=newJob(logWriter,StepLoader.getInstance(),repository,jobMeta);
由于Job一般都沒有什么返回值,所以Job不需要初始化它下面的對(duì)象,直接開場(chǎng)運(yùn)行就可以了
job.start();
job.waitUntilFinished(5000000);連接資源庫(kù)
連接資源庫(kù)使用的是connectToRepository()方法,先取得RepositoriesMeta對(duì)象,然后根據(jù)你在setting.*ml文件里面定義的repository的名字來連接對(duì)應(yīng)的repository.理論上來說我們一般都只使用一個(gè)repository,但如果在產(chǎn)品中需要使用多個(gè)repository的話,你需要自己配置多個(gè)repository的名字和對(duì)應(yīng)的用戶名和密碼。只列出幾行關(guān)鍵代碼,
repositoriesMeta=newRepositoriesMeta(logWriter);
repositoriesMeta.readData();//從$HOME/.kettle/repositories.*ml讀數(shù)據(jù).
repositoryMeta=repositoriesMeta.findRepository(repositoryName);
repository=newRepository(logWriter,repositoryMeta,userInfo);
userInfo=newUserInfo(repository,username,password);從資源庫(kù)讀取Trans
連接到資源庫(kù)之后自然是想方法讀取數(shù)據(jù)庫(kù)的表,把里面的記錄轉(zhuǎn)換成為Trans對(duì)象,使用的是loadTransformFromRepository,這個(gè)方法的函數(shù)原型需要解釋一下:
TransMetaloadTransformFromRepository(StringdirectoryName,StringtransformationName,Repositoryrepository,LogWriterlogWriter)
第一個(gè)參數(shù)StringdirectoryName代表是你儲(chǔ)存轉(zhuǎn)換的目錄,當(dāng)你使用kettle圖形界面的時(shí)候,點(diǎn)擊repository菜單的e*plorerrepository,你會(huì)發(fā)現(xiàn)你所有的東西都是存儲(chǔ)在一個(gè)虛擬的類似與目錄構(gòu)造的地方,其中包括databaseconnections,transformations,job,users等,所以你需要的是指定你連接的目錄位置,你也可以在目錄里面再創(chuàng)立目錄。
StringtransformationName自然指的就是你轉(zhuǎn)換的名字.
Repositoryrepository指的是你連接的資源庫(kù)。
LogWriterlogWriter指定你的日志輸出,這個(gè)log指的是你kettle轉(zhuǎn)換的日志輸出,不是應(yīng)用程序本身的輸出。
讀取TransMeta的步驟也相比照擬簡(jiǎn)單
repositoryDirectory=repository.getDirectoryTree().findDirectory(directoryName);
transMeta=newTransMeta(repository,transformationName,repositoryDirectory);從資源庫(kù)讀取Job
從資源庫(kù)讀取Job跟Trans的步驟根本是一樣的,同樣需要指定你存儲(chǔ)Job的目錄位置.
JobMetaloadJobFromRepository(StringdirectoryName,StringjobName,
Repositoryrepository,LogWriterlogWriter)讀取結(jié)果集
一般Job都是不會(huì)返回任何結(jié)果集的,大局部Trans也不會(huì)返回結(jié)果集,應(yīng)為結(jié)果集一般都會(huì)直接從一個(gè)數(shù)據(jù)庫(kù)到另一個(gè)數(shù)據(jù)庫(kù)了,但是如果你需要返回轉(zhuǎn)換的結(jié)果集,則這一小結(jié)將會(huì)向你解釋如何從一個(gè)Trans里面讀取這些結(jié)果集
首先,你需要一個(gè)容納Result的容器,就是類似與JDBC里面的resultSet,resultSet當(dāng)然會(huì)有一個(gè)resultSetMetadata跟它相關(guān)聯(lián),在本文所舉的實(shí)例中,使用的是pentaho私有的memoryResultSet,
你可以不用關(guān)心它的細(xì)節(jié),并且它的類型正如它的名字一樣是存在與Memory的,所以它不能被持久化,這個(gè)里面儲(chǔ)存的是一個(gè)二維的Object數(shù)組,里面的數(shù)據(jù)就是從kettle轉(zhuǎn)化之后來的。
要從kettle的轉(zhuǎn)換中讀取結(jié)果集,要實(shí)現(xiàn)RowListener接口,Row是kettle里面表示一行數(shù)據(jù)的一個(gè)類,RowListener自然是指在轉(zhuǎn)換數(shù)據(jù)轉(zhuǎn)換的時(shí)候發(fā)生的事件,它有三個(gè)方法需要實(shí)現(xiàn),
voidrowReadEvent〔Row〕
voidrowWrittenEvent(Row)
voiderrorRowWrittenEvent(Row)
分別對(duì)應(yīng)讀數(shù)據(jù)時(shí)的事件,寫數(shù)據(jù)事的時(shí)間,出錯(cuò)時(shí)的時(shí)間,我們需要取得結(jié)果集,所以只需要實(shí)現(xiàn)rowWrittenEvent(Row)就可以了,Row對(duì)象是通過TransMeta取得的,
Rowrow=transMeta.getStepFields(stepName);
下面給出具體實(shí)現(xiàn)取Row轉(zhuǎn)換成resultSet的代碼:
ObjectpentahoRow[]=newObject[results.getColumnCount()];
for(intcolumnNo=0;columnNo<results.getColumnCount();columnNo++){
Valuevalue=row.getValue(columnNo);
switch(value.getType()){
caseValue.VALUE_TYPE_BIGNUMBER:
pentahoRow[columnNo]=value.getBigNumber();
break;
........results.addRow(pentahoRow);
默認(rèn)的數(shù)據(jù)類型是String類型〔在省略局部〕.
整個(gè)代碼最重要的一行是Valuevalue=row.getValue(columnNo);
這是真正取得實(shí)際數(shù)據(jù)的一行。有時(shí)候你會(huì)覺得實(shí)現(xiàn)一個(gè)resultSet比擬麻煩,尤其是你還要實(shí)現(xiàn)相關(guān)的resultSetMetaData,怎么把數(shù)據(jù)轉(zhuǎn)換成你自己的類型,你大可以就用一個(gè)ListofList來實(shí)現(xiàn),里面的List就代表Row的對(duì)應(yīng)數(shù)據(jù),外面一層List就是result,整個(gè)代碼會(huì)簡(jiǎn)單一些,當(dāng)然,你要自己知道最后這個(gè)List怎么用.本文有意隱藏了一些跟pentaho有關(guān)的細(xì)節(jié),比方validateSystemSettings(),init〔〕,validateAction〔〕方法,這些都是pentaho私有的,有些方法比方rowWrittenEvent(Row)是用來取結(jié)果集的,但是很多時(shí)候我們不需要取轉(zhuǎn)換的結(jié)果集,文中很多代碼都只列出主要的局部,省略一些判斷,調(diào)試,log局部的代碼,大家可以自己下載這些代碼來研究,
本文并沒有給出一個(gè)可以獨(dú)立運(yùn)行的例如,因?yàn)檫@個(gè)例如一定會(huì)太過于簡(jiǎn)單〔不超過15行代碼〕,但是卻并不能考慮到各種情況,連接資源庫(kù)還是文件,運(yùn)行轉(zhuǎn)換還是Job,metadata怎么得來的,需不需要轉(zhuǎn)換之后的結(jié)果。
關(guān)于在本文一開場(chǎng)提到的使用kettle的兩種方式,對(duì)于第二種使用方式:使用完全編程的方式來運(yùn)行轉(zhuǎn)換,其實(shí)它的與第一種方式的區(qū)別就好似一個(gè)用設(shè)計(jì)器來寫*ml文件,一個(gè)用純手工方式寫*ml文件〔用代碼的*ml〕,大家可以參考官方上的一段例如代碼,地址如下:
開源ETL工具kettle系列之增量更新設(shè)計(jì)ETL中增量更新是一個(gè)比擬依賴與工具和設(shè)計(jì)方法的過程,Kettle中主要提供Insert/Update步驟,Delete步驟和DatabaseLookup步驟來支持增量更新,增量更新的設(shè)計(jì)方法也是根據(jù)應(yīng)用場(chǎng)景來選取的,雖然本文討論的是Kettle的實(shí)現(xiàn)方式,但也許對(duì)其他工具也有一些幫助。本文不可能涵蓋所有的情況,歡送大家討論。應(yīng)用場(chǎng)景
增量更新按照數(shù)據(jù)種類的不同大概可以分成:
1.
只增加,不更新,
2.
只更新,不增加
3.
即增加也更新
4.
有刪除,有增加,有更新
其中1,2,3種大概都是一樣的思路,使用的步驟可能略有不同,通用的方法是在原數(shù)據(jù)庫(kù)增加一個(gè)時(shí)間戳,然后在轉(zhuǎn)換之后的對(duì)應(yīng)表保存這個(gè)時(shí)間戳,然后每次抽取數(shù)據(jù)的時(shí)候,先讀取這個(gè)目標(biāo)數(shù)據(jù)庫(kù)表的時(shí)間戳的最大值,把這個(gè)值當(dāng)作參數(shù)傳給原數(shù)據(jù)庫(kù)的相應(yīng)表,根據(jù)這個(gè)時(shí)間戳來做限定條件來抽取數(shù)據(jù),抽取之后同樣要保存這個(gè)時(shí)間戳,并且原數(shù)據(jù)庫(kù)的時(shí)間戳一定是指定默認(rèn)值為sysdate當(dāng)前時(shí)間〔以原數(shù)據(jù)庫(kù)的時(shí)間為標(biāo)準(zhǔn)〕,抽取之后的目標(biāo)數(shù)據(jù)庫(kù)的時(shí)間戳要保存原來的時(shí)間戳,而不是抽取時(shí)候的時(shí)間。
對(duì)于第一種情況,可以使用Kettle的Insert/Update步驟,只是可以勾選Don’tperformanyupdate選項(xiàng),這個(gè)選項(xiàng)可以告訴Kettle你只會(huì)執(zhí)行Insert步驟。
對(duì)于第二種情況可能比擬用在數(shù)據(jù)出現(xiàn)錯(cuò)誤然后原數(shù)據(jù)庫(kù)有一些更新,相應(yīng)的目標(biāo)數(shù)據(jù)庫(kù)也要更新,這時(shí)可能不是更新所有的數(shù)據(jù),而是有一些限定條件的數(shù)據(jù),你可以使用Kettle的Update步驟來只執(zhí)行更新。關(guān)于如何動(dòng)態(tài)的執(zhí)行限定條件,可以參考前一篇文章。
第三種情況是最為常見的一種情況,使用的同樣是Kettle的Insert/Update步驟,只是不要勾選Don’tperformanyupdate選項(xiàng)。
第四種情況有些復(fù)雜,后面專門討論。對(duì)于第1,2,3種情況,可以參考下面的例子。
這個(gè)例子假設(shè)原數(shù)據(jù)庫(kù)表為customers,含有一個(gè)id,firstname,lastname,age字段,主鍵為id,然后還加上一個(gè)默認(rèn)值為sysdate的時(shí)間戳字段。轉(zhuǎn)換之后的結(jié)果類似:id,firstname,lastname,age,updatedate.整個(gè)設(shè)計(jì)流程大概如下:
圖1
其中第一個(gè)步驟的sql大概如下模式:
Selectma*(updatedate)fromtarget_customer;
你會(huì)注意到第二個(gè)步驟和第一個(gè)步驟的連接是黃色的線,這是因?yàn)榈诙€(gè)tableinput步驟把前面一個(gè)步驟的輸出當(dāng)作一個(gè)參數(shù)來用,所有Kettle用黃色的線來表示,第二個(gè)tableinput的sql模式大概如下:
Selectfield1,field2,field3fromcustomerswhereupdatedate>"
后面的一個(gè)問號(hào)就是表示它需要承受一個(gè)參數(shù),你在這個(gè)tableinput下面需要指定replacevariableinscript選項(xiàng)和e*ecuteforeachrow為選中狀態(tài),這樣,Kettle就會(huì)循環(huán)執(zhí)行這個(gè)sql,執(zhí)行的次數(shù)為前面參數(shù)步驟傳入的數(shù)據(jù)集的大小。
圖2關(guān)于第三個(gè)步驟執(zhí)行insert/update步驟需要特別解釋一下,
圖3Kettle執(zhí)行這個(gè)步驟是需要兩個(gè)數(shù)據(jù)流比照,其中一個(gè)是目標(biāo)數(shù)據(jù)庫(kù),你在Targettable里面指定的,它放在Thekeystolookupthevalues(s)左邊的Tablefield里面的,另外一個(gè)數(shù)據(jù)流就是你在前一個(gè)步驟傳進(jìn)來的,它放在Thekeystolookupthevalue(s)的右邊,Kettle首先用你傳進(jìn)來的key在數(shù)據(jù)庫(kù)中查詢這些記錄,如果沒有找到,它就插入一條記錄,所有的值都跟你原來的值一樣,如果根據(jù)這個(gè)key找到了這條記錄,kettle會(huì)比擬這兩條記錄,根據(jù)你指定updatefield來比擬,如果數(shù)據(jù)完全一樣,kettle就什么都不做,如果記錄不完全一樣,kettle就執(zhí)行一個(gè)update步驟。所以首先你要確保你指定的key字段能夠唯一確定一條記錄,這個(gè)時(shí)候會(huì)有兩種情況:
1.維表
2.事實(shí)表
維表大都是通過一個(gè)主鍵字段來判斷兩條記錄是否匹配,可能我們的原數(shù)據(jù)庫(kù)的主鍵記錄不一定對(duì)應(yīng)目標(biāo)數(shù)據(jù)庫(kù)中相應(yīng)的表的主鍵,這個(gè)時(shí)候原數(shù)據(jù)庫(kù)的主鍵就變成了業(yè)務(wù)主鍵,你需要根據(jù)*種條件判斷這個(gè)業(yè)務(wù)主鍵是否相等,想象一下如果是多個(gè)數(shù)據(jù)源的話,業(yè)務(wù)主鍵可能會(huì)有重復(fù),這個(gè)時(shí)候你需要比擬的是根據(jù)你自定義生成的新的實(shí)際的主鍵,這種主鍵可能是根據(jù)*種類似與sequence的生成方式生成的,
事實(shí)表在經(jīng)過轉(zhuǎn)換之后,進(jìn)目標(biāo)數(shù)據(jù)庫(kù)之前往往都是通過多個(gè)外鍵約束來確定唯一一條記錄的,這個(gè)時(shí)候比擬兩條記錄是否相等都是通過所有的維表的外鍵決定的,你在比擬了記錄相等或不等之后,還要自己判斷是否需要添加一個(gè)新的主鍵給這個(gè)新記錄。
上面兩種情況都是針對(duì)特定的應(yīng)用的,如果你的轉(zhuǎn)換過程比擬簡(jiǎn)單,只是一個(gè)原數(shù)據(jù)庫(kù)對(duì)應(yīng)一個(gè)目標(biāo)數(shù)據(jù)庫(kù),業(yè)務(wù)主鍵跟代理主鍵完全一樣的時(shí)候完全可以不用考慮這么多。有刪除,有增加,有更新
首先你需要判斷你是否在處理一個(gè)維表,如果是一個(gè)維表的話,則這可能是一個(gè)SCD情況,可以使用Kettle的DimensionLookup步驟來解決這個(gè)問題,如果你要處理的是事實(shí)表,方法就可能有所不同,它們之間的主要區(qū)別是主鍵的判斷方式不一樣。
事實(shí)表一般都數(shù)據(jù)量很大,需要先確定是否有變動(dòng)的數(shù)據(jù)處在*一個(gè)明確的限定條件之下,比方時(shí)間上處在*個(gè)特定區(qū)間,或者*些字段有*種限定條件,盡量最大程度的先限定要處理的結(jié)果集,然后需要注意的是要先根據(jù)id來判斷記錄的狀態(tài),是不存在要插入新紀(jì)錄,還是已存在要更新,還是記錄不存在要?jiǎng)h除,分別對(duì)于id的狀態(tài)來進(jìn)展不同的操作。
處理刪除的情況使用Delete步驟,它的原理跟Insert/Update步驟一樣,只不過在找到了匹配的id之后執(zhí)行的是刪除操作而不是更新操作,然后處理Insert/Update操作,你可能需要重新創(chuàng)立一個(gè)轉(zhuǎn)換過程,然后在一個(gè)Job里面定義這兩個(gè)轉(zhuǎn)換之間的執(zhí)行順序。
如果你的數(shù)據(jù)變動(dòng)量比擬大的話,比方超過了一定的百分比,如果執(zhí)行效率比擬低下,可以適當(dāng)考慮重新建表。
另外需要考慮的是維表的數(shù)據(jù)刪除了,對(duì)應(yīng)的事實(shí)表或其他依賴于此維表的表的數(shù)據(jù)如何處理,外鍵約束可能不太容易去掉,或者說一旦去掉了就可能再加上去了,這可能需要先處理好事實(shí)表的依賴數(shù)據(jù),主要是看你如何應(yīng)用,如果只是簡(jiǎn)單的刪除事實(shí)表數(shù)據(jù)的話還比擬簡(jiǎn)單,但是如果需要保存事實(shí)表相應(yīng)記錄,可以在維表中增加一條記錄,這條記錄只有一個(gè)主鍵,其他字段為空,當(dāng)我們刪除了維表數(shù)據(jù)后,事實(shí)表的數(shù)據(jù)就更新指向這條空的維表記錄。
定時(shí)執(zhí)行增量更新
可能有時(shí)候我們就是定時(shí)執(zhí)行更新操作,比方每天或者一個(gè)星期一次,這個(gè)時(shí)候可以不需要在目標(biāo)表中增加一個(gè)時(shí)間戳字段來判斷ETL進(jìn)展的最大時(shí)間,直接在取得原數(shù)據(jù)庫(kù)的時(shí)間加上限定條件比方:
Startdate>"andenddate<"
或者只有一個(gè)startdate
Startdate>"
(昨天的時(shí)間或者上個(gè)星期的時(shí)間)
這個(gè)時(shí)候需要傳一個(gè)參數(shù),用getSystemInfo步驟來取得,而且你還可以控制時(shí)間的精度,比方到天而不是到秒的時(shí)間。
當(dāng)然,你也需要考慮一下如果更新失敗了怎么處理,比方*一天因?yàn)?種原因沒有更新,這樣可能這一天的記錄需要手工處理回來,如果失敗的情況經(jīng)??赡馨l(fā)生,那還是使用在目標(biāo)數(shù)據(jù)庫(kù)中增加一個(gè)時(shí)間字段取最大時(shí)間戳的方式比擬通用,雖然它多了一個(gè)很少用的字段。
執(zhí)行效率和復(fù)雜度
刪除和更新都是一項(xiàng)比擬消耗時(shí)間的操作,它們都需要不斷的在數(shù)據(jù)庫(kù)中查詢記錄,執(zhí)行刪除操作或更新操作,而且都是一條一條的執(zhí)行,執(zhí)行效率低下也是可以預(yù)見的,盡量可能的縮小原數(shù)據(jù)集大小。減少傳輸?shù)臄?shù)據(jù)集大小,降低ETL的復(fù)雜程度
時(shí)間戳方法的一些優(yōu)點(diǎn)和缺點(diǎn)
優(yōu)點(diǎn):
實(shí)現(xiàn)方式簡(jiǎn)單,很容易就跨數(shù)據(jù)庫(kù)實(shí)現(xiàn)了,運(yùn)行起來也容易設(shè)計(jì)
缺點(diǎn):浪費(fèi)大量的儲(chǔ)存空間,時(shí)間戳字段除ETL過程之外都不被使用,如果是定時(shí)運(yùn)行的,*一次運(yùn)行失敗了,就有可能造成數(shù)據(jù)有局部喪失.
其他的增量更新方法:
增量更新的核心問題在與如何找出自上次更新以后的數(shù)據(jù),其實(shí)大多數(shù)數(shù)據(jù)庫(kù)都能夠有方法捕捉這種數(shù)據(jù)的變化,比擬常見的方式是數(shù)據(jù)庫(kù)的增量備份和數(shù)據(jù)復(fù)制,利用數(shù)據(jù)庫(kù)的管理方式來處理增量更新就是需要有比擬好的數(shù)據(jù)庫(kù)管理能力,大多數(shù)成熟的數(shù)據(jù)庫(kù)都提供了增量備份和數(shù)據(jù)復(fù)制的方法,雖然實(shí)現(xiàn)上各不一樣,不過由于ETL的增量更新對(duì)數(shù)據(jù)庫(kù)的要只要數(shù)據(jù),其他的數(shù)據(jù)庫(kù)對(duì)象不關(guān)心,也不需要完全的備份和完全的standby數(shù)據(jù)庫(kù),所以實(shí)現(xiàn)方式還是比擬簡(jiǎn)單的.,只要你創(chuàng)立一個(gè)與原表構(gòu)造類似的表構(gòu)造,然后創(chuàng)立一個(gè)三種類型的觸發(fā)器,分別對(duì)應(yīng)insert,update,delete操作,然后維護(hù)這個(gè)新表,在你進(jìn)展ETL的過程的時(shí)候,將增量備份或者數(shù)據(jù)復(fù)制停頓,然后開場(chǎng)讀這個(gè)新表,在讀完之后將這個(gè)表里面的數(shù)據(jù)刪除掉就可以了,不過這種方式不太容易定時(shí)執(zhí)行,需要一定的數(shù)據(jù)庫(kù)特定的知識(shí)。如果你對(duì)數(shù)據(jù)的實(shí)時(shí)性要求比擬高可以實(shí)現(xiàn)一個(gè)數(shù)據(jù)庫(kù)的數(shù)據(jù)復(fù)制方案,如果對(duì)實(shí)時(shí)性的要求比擬低,用增量備份會(huì)比擬簡(jiǎn)單一點(diǎn)。
幾點(diǎn)需要注意的地方:
1.觸發(fā)器
無論是增量備份還是數(shù)據(jù)復(fù)制,如果原表中有觸發(fā)器,在備份的數(shù)據(jù)庫(kù)上都不要保存觸發(fā)器,因?yàn)槲覀冃枰牟皇且粋€(gè)備份庫(kù),只是需要里面的數(shù)據(jù),最好所有不需要的數(shù)據(jù)庫(kù)對(duì)象和一些比擬小的表都不用處理。
2.邏輯一致和物理一致
數(shù)據(jù)庫(kù)在數(shù)據(jù)庫(kù)備份和同步上有所謂邏輯一致和物理一致的區(qū)別,簡(jiǎn)單來說就是同一個(gè)查詢?cè)趥浞輸?shù)據(jù)庫(kù)上和主數(shù)據(jù)庫(kù)上得到的總的數(shù)據(jù)是一樣的,但是里面每一條的數(shù)據(jù)排列方式可能不一樣,只要沒有明顯的排序查詢都可能有這種情況〔包括groupby,distinct,union等〕,而這可能會(huì)影響到生成主鍵的方式,需要注意在設(shè)計(jì)主鍵生成方式的時(shí)候最好考慮這一點(diǎn),比方顯式的增加order排序.防止在數(shù)據(jù)出錯(cuò)的時(shí)候,如果需要重新讀一遍數(shù)據(jù)的時(shí)候主鍵有問題.
總結(jié)
增量更新是ETL中一個(gè)常見任務(wù),對(duì)于不同的應(yīng)用環(huán)境可能采用不同的策略,本文不可能覆蓋所有的應(yīng)用場(chǎng)景,像是多個(gè)數(shù)據(jù)源匯到一個(gè)目標(biāo)數(shù)據(jù)庫(kù),id生成策略,業(yè)務(wù)主鍵和代理主鍵不統(tǒng)一等等,只是希望能給出一些思路處理比擬常見的情況,希望能對(duì)大家有所幫助。
開源ETL工具kettle系列之動(dòng)態(tài)轉(zhuǎn)換摘要:本文主要討論使用Kettle來設(shè)計(jì)一些較為復(fù)雜和動(dòng)態(tài)的轉(zhuǎn)換可能使用到的一些技巧,這些技巧可能會(huì)讓你在使用Kettle的時(shí)候更加容易的設(shè)計(jì)更強(qiáng)大的ETL任務(wù)。動(dòng)態(tài)參數(shù)的傳遞
Kettle在處理運(yùn)行時(shí)輸入?yún)?shù)可以使用JavaScript來實(shí)現(xiàn),大局部工作只是按照一個(gè)模板來處理的
動(dòng)態(tài)參數(shù)傳遞主要使用在像數(shù)據(jù)清理,調(diào)式,測(cè)試,完成復(fù)雜的條件過濾等等,這種方式一般不會(huì)在產(chǎn)品已經(jīng)運(yùn)行穩(wěn)定了一段時(shí)間之后使用,因?yàn)槲覀円话闳匀皇亲龆〞r(shí)任務(wù)來自動(dòng)轉(zhuǎn)換數(shù)據(jù),所以在開場(chǎng)介紹如何使用動(dòng)態(tài)參數(shù)之前,希望大家能明白不要在產(chǎn)品數(shù)據(jù)庫(kù)上做實(shí)驗(yàn),即使你已經(jīng)知道你的轉(zhuǎn)換有什么影響并且做了備份,因?yàn)檫@種方法是不可能自動(dòng)執(zhí)行的。
Kettle有兩種動(dòng)態(tài)參數(shù)傳遞的方法,一種是非常輕量級(jí)的傳argument,另一種是對(duì)付較復(fù)雜一點(diǎn)情況使用JavaScript.下面分別介紹這兩種方法。
1.
argument
當(dāng)你在運(yùn)行一個(gè)轉(zhuǎn)換的時(shí)候,不管這個(gè)轉(zhuǎn)換是一個(gè)Job的一局部還是只有這個(gè)轉(zhuǎn)換,你都可以傳遞參數(shù)給它,當(dāng)你運(yùn)行一個(gè)轉(zhuǎn)換的時(shí)候,會(huì)彈出一個(gè)E*ecutionaTransformation的對(duì)話框,讓你選擇執(zhí)行轉(zhuǎn)換的方式,本地執(zhí)行,遠(yuǎn)程執(zhí)行,分布式執(zhí)行,下面就是日志記錄的級(jí)別和回放時(shí)間,然后是argument和variables的設(shè)定。Argument和variables的區(qū)別在官方FAQ里面也有解釋。你也可以參考一下官方的解釋和下面解釋的異同。
Q:Argument和variables的區(qū)別/
A:variables也可以認(rèn)為叫做environmentvariables,就像它的名字一樣,主要是用來設(shè)定環(huán)境變量的,比方最常見的:文件的存放地址,smtp的配置等等,你也可以把它認(rèn)為是編程語(yǔ)言里面的全局變量,即使是不同的轉(zhuǎn)換它們也擁有同樣的值,而argument自然就類似與局部變量,只針對(duì)一個(gè)特定的轉(zhuǎn)換,比方像是限定結(jié)果集的大小和過濾條件。取得argument的值
我們?cè)谵D(zhuǎn)換之前設(shè)置了argument的值,需要用到的時(shí)候就使用getsysteminfo步驟,這個(gè)步驟取得在運(yùn)行時(shí)參數(shù),需要注意的是我們是先設(shè)置getsysteminfo,然后在里面決定要使用多少個(gè)參數(shù),最多10個(gè),每個(gè)參數(shù)名叫什么,然后我們才能在運(yùn)行時(shí)看到你設(shè)置了的參數(shù)名后面跟一個(gè)要你輸入的值,并且參數(shù)類型是不能夠指定,全部都當(dāng)作字符串處理,如果你需要對(duì)參數(shù)類型有要求,你需要自己轉(zhuǎn)換,使用一個(gè)Mapping步驟或者Selectvalues步驟。
取得variable的值
Variable的值個(gè)數(shù)不受限制,你可以在kettle菜單的setenvironment里面設(shè)置,也可以使用文件儲(chǔ)存這些值,在第一次運(yùn)行kettle之后,kettle會(huì)在%HOME_USER_FOLDER%菜單里面創(chuàng)立一個(gè).kettle文件夾,如果是windows用戶可能就是C:\DocumentsandSettings\${yourusername}\.kettle這個(gè)文件夾,如果是linu*用戶可能就是/home/${yourusername}/.kettle文件夾,這個(gè)文件夾下面有perties文件,如果你翻開這個(gè)文件,你會(huì)發(fā)現(xiàn)里面有一些以*開頭的注釋,其中設(shè)置了一些像是:PRODUCTION_SERVER=Hercules這樣的鍵值對(duì),你可以自己定義一些環(huán)境變量比方像是smtp的地址,ftp效勞器的地址,你放log文件的目錄名等等,當(dāng)然不能直接編輯這個(gè)文件就設(shè)置環(huán)境變量,要先設(shè)置KETTLE_HOME環(huán)境變量,windows就是點(diǎn)我的電腦,然后在設(shè)置path的那個(gè)地方添加一個(gè)KETTLE_HOME變量,linu*就是e*portKETTLE_HO
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 小學(xué)二年級(jí)描寫小貓的作文200字
- Thalidomide-5-Br-生命科學(xué)試劑-MCE
- Terazosin-hydrochloride-dihydrate-Standard-生命科學(xué)試劑-MCE
- Sulfabenzamide-Standard-生命科學(xué)試劑-MCE
- 部編版七年級(jí)下冊(cè)道德與法治第六課“我”和“我們”作業(yè)題1
- 2024-2025學(xué)年高中歷史第三單元北魏孝文帝改革第1課改革迫在眉睫課后鞏固訓(xùn)練含解析新人教版選修1
- 2024高一地理寒假作業(yè)同步練習(xí)題自然地理環(huán)境的差異性含解析
- 2024-2025學(xué)年新教材高中物理第一章運(yùn)動(dòng)的描述4速度變化快慢的描述-加速度學(xué)案新人教版必修1
- 2025版高考地理第4單元中國(guó)地理概況第3課時(shí)中國(guó)的氣候達(dá)標(biāo)練含解析
- 六年級(jí)語(yǔ)文楚才杯雨還在下獲獎(jiǎng)作文27
- GB/T 41715-2022定向刨花板
- YC/T 384.3-2018煙草企業(yè)安全生產(chǎn)標(biāo)準(zhǔn)化規(guī)范第3部分:考核評(píng)價(jià)準(zhǔn)則和方法
- 夏商周考古課件 第5章 西周文化(3節(jié))
- GB/T 7324-2010通用鋰基潤(rùn)滑脂
- GB/T 4459.1-1995機(jī)械制圖螺紋及螺紋緊固件表示法
- 危險(xiǎn)化學(xué)品安全告知牌硝酸、鹽酸、硫酸、氫氧化鈉
- GB/T 29163-2012煤矸石利用技術(shù)導(dǎo)則
- 上海英文介紹課件
- 上交所個(gè)股期權(quán)基礎(chǔ)知識(shí)課件
- 最新山羊、綿羊人工授精技術(shù)及新技術(shù)介紹(含人工授精視頻)課件
- 2022年征信知識(shí)競(jìng)賽基礎(chǔ)題題庫(kù)(含各題型)
評(píng)論
0/150
提交評(píng)論