kettle的並行,集羣和分區

轉載自:http://www.ahuoo.com/?p=616        


        當你有很多數據要處理的時候,能夠有效地使用所有的計算資源是非常重要的。不管是臺個人電腦,還是有數百臺服務器,你都想讓Kettle能儘可能的使用所有可用的計算資源,並在可接受的時間範圍內獲取執行結果。

        在這一章節,我們將解開kettle的轉換和作業在垂直擴展和水平擴展方面的祕密。垂直擴展是儘可能的使用單臺服務器上的多CPU核。水平擴展是使用多臺機器資源,使他們並行計算。這兩種方法都是ETL子系統的一部分(#31,並行/流水線系統)。

章節的第一部分先談談轉換內部的並行機制和多種使用其進行垂直擴展的方法。然後我們講解怎樣在子服務器集羣環境下進行水平擴展轉換。

       最後我們講講kettle分區的一些具體細節,利用分區進一步提升並行計算的性能。

       東西有點多,還是先在這裏列一下討論的主題,分別是:

一、多線程
二、多線程的後果
三、用Carte作爲子服務器
四、集羣轉換
五、分區

 

一、多線程

        在章節2中,我們已經瞭解了轉換的基本組成部分是步驟,而且每個步驟是並行執行的。現在我們將更深入這一話題,解釋kettle的多線程能力怎樣使你更充分利用機器所有的計算資源,垂直擴展一個轉換。

        默認情況下,轉換中的每一個步驟都是在單一隔離的線程裏面並行的執行。但可以爲任何單一的步驟增加線程的數目,也可叫做複製。在15章裏我們也解釋過,這種辦法能夠提高那些CPU時間消耗量大的轉換步驟的性能。[*1]

讓我們看一個簡單的例子,如圖16-1,其中所有數據的記錄都被一個User Defined Java Class步驟處理

16-1

圖16-1:一個簡單的轉換

你可以右鍵這個User Defined Java Class步驟,選擇菜單中的“改變開始複製的數量”,如果你指定4份,你將看到轉換的圖形表示如下,見圖16-2

16-2

圖16-2:在多個複製下運行一個步驟

這個“4x”的符號指示了4個複製將在運行的時候被啓動。

注意:所有步驟複製只維護一份步驟的描述,[*2]

爲了理解接下來的章節,這兒定義幾個專業術語:

  • Step: 描敘需要做的某項工作的定義或元數據
  • Step copy: 在步驟裏定義的執行某項工作的一個並行工作線程

換句話說,一個step僅僅是任務的定義,而一個step copy則表示一個實際執行的任務。

記錄行分發

在這個例子裏,你使得一個步驟複製發送記錄給4個步驟複製,所以這些記錄是怎樣分發給目標步驟複製的呢?默認情況下,分發工作在一個循環的方式下執行。也就是說如果有N份複製,第一份複製獲取第一條記錄,第二份複製獲取第二條記錄,第N份複製接受第N條記錄。記錄N+1又分發給第一份複製,依此類推,直到沒有記錄分發爲止。

這裏還有另外一個比較少用的功能,使用它可以將所有的記錄發送給所有的複製,你可以在步驟的上下文菜單中啓用這個“複製數據到所有的步驟”選項。這個選項會發送這些記錄到多個目標的步驟,例如同時往數據庫表和文件裏面寫入數據。 在例子中,會得到一個警告對話框,見圖:16-3,詢問你選哪個選項

16-3

圖16-3:一個警告對話框

選擇Copy,可拷貝所有的數據記錄給數據庫和文本文件,這個轉換結果看起來像下面這個例子,見圖16-4[*3]

16-4

圖16-4: 拷貝數據到多個目標步驟

這應該是個例外,通常情況是處理每一條記錄僅僅一次(而不是處理多次),餘下的章節中的例子使用的是記錄的分發,而非複製。[*4]

記錄行合併

記錄合併發生在幾個步驟或者步驟複製發送多條記錄給單個步驟複製時。圖16-5顯示了2個這樣的例子。

如果站在步驟“Text file output” 和 “Add sequence”的角度考慮,記錄集從每個源步驟複製裏面不是一次性讀取(而是一行一行的讀取),當一個步驟複製正在以緩慢的步伐發送少量的數據記錄,而另外一個步驟複製正在以迅速的步伐產生記錄集,而此時從源步驟複製裏批次讀取數據行,那可能導致嚴重的性能問題,。[*5]

警告:從前一步驟讀取記錄行的順序是決不保證的!

16-5

圖16-5:合併數據的記錄行

記錄行再分發

在記錄行再分發裏,你有X個步驟複製發送記錄集給Y個目標步驟複製,想想圖16-6的這個例子:

圖16-6 記錄行再分發

同樣的規則適用於之前的記錄集分發:在這個實例中,User Defined Java Class的3個源步驟複製每一個都分發記錄集給2個目標步驟複製。這個結果等同於圖16-7裏面顯示的轉換。

這個再分發算法的主要優勢是記錄集被平等的分發給這些驟複製,防止了轉換裏面某個步驟複製有很多工作,而其他僅僅有一點工作乾的情形。

正如你在圖16-7裏面看到的,有X乘Y行緩衝區被分配在UDJC和Formula步驟之間。在我們的例子中,有6個緩衝區(箭頭)被分配給3個源步驟和2個目標步驟。在設計轉換的時候得記住這一點哦,特別是在你的轉換末端有很慢的步驟時,這些緩存能夠被填滿到達它們的最大值“Row set size” ,那反過來會增加你的轉換的內存消耗。例如,看看圖16-8裏面的一個例子:

圖16-7:記錄行再分發展開

圖16-8:再分發會分配若干緩衝區

儘管你僅僅看到一個單箭頭在轉換裏面,其實這裏你有5個來源步驟和4個目標步驟複製,而且有20個緩衝區被分配了。默認情況下最大記錄行設置爲10000, 所以內存中能保存的記錄行總數是200000。

數據流水線

數據流水線是再分發的一個特例,它的來源和目標步驟複製是一樣的(X==Y)。這種情況下,記錄集絕不是通過所有的步驟複製被再分發的,相反,由源步驟複製1產生的記錄集被髮送到具有相同編號的目標步驟複製,圖16-9提供了一個這樣的轉換例子:

圖16-9:數據流水線

在技術上,它等同於圖16-10表示的轉換

圖16-10:數據流水線展開

分發和合並記錄行的過程中有一點但是可衡量的開銷,通常情況下,最好讓連續的步驟複製數目保持一樣,用來減少這個開銷

這種減少步驟複製之間數據通訊的開銷的過程,也可形象的比喻爲將數據放進游泳池通道(彼此之間可不受干擾)。

二、多線程的後果

在先前的部分,我們學習到了一個轉換是多線程的,並且所有的步驟都並行運行。接下來我們會告訴你此執行模式可能帶來的後果,以及如何處理那些後果。

數據庫連接

在多線程軟件下處理數據庫連接,最推薦的方法是在轉換執行的過程中爲每個線程創建單一的連接。因此,每個步驟複製都打開它們自己單獨的事務或者事務集。

這將導致一個潛在的後果,就是你在使用同一個數據庫資源的場景下,例如一張數據表或者視圖,條件競爭在同一個轉換中可能而且會經常發生。

一個常見產生錯誤的場景,就是當你往一個關係數據表裏面寫入數據,在隨後的步驟裏面讀回。因爲這兩個步驟運行在不同的數據庫連接下,而且擁有不同的事務上下文,你不能確保這個被第一個步驟寫入的數據將可見於其他正在執行讀操作的步驟。

一個常見,且簡單的解決這個問題的方案就是將這個轉換分成2個不同的轉換,然後保存數據在臨時表或者文件中。

另外一個方案是強制使所有的步驟使用單一數據庫連接(僅一個事務),啓用轉換設置對話框中的“Make the transformation database transactional”選項即可,見圖16-11

圖16-11 設置一個轉換事務

這個選項意味着Kettle將在每個命名的數據庫中,僅僅使用單一連接,直到轉換執行完畢之後才執行事務的提交或者回滾。一個事務在執行過程中完全沒有錯誤才提交,有任何錯誤就回滾。請注意被步驟錯誤處理的任何錯誤都不會導致事務的回滾。(這個其實跟java裏面的事務處理機制一樣)。

使用這個選項的缺點就是會降低轉換的性能,這裏有很多的原因,可以是現在所有的數據庫通訊都交給了一個同步連接,也可以是往往只有一個單一服務器端進程處理請求[*6]

執行的順序

由於所有步驟並行的執行,所以轉換中的步驟沒有特定的執行順序,但是在數據集成過程中仍然有些東西需要按某種順序執行。在大多數情況下,解決這個問題的方案是創建一個作業,使得任務按特定的順序執行。

在kettle的轉換中,也有些步驟強制按某種順序執行,幾個小技巧如下.[*7]

執行腳本步驟

如果你想在轉換中,執行一個優先於所有步驟的SQL,可以使用執行腳本步驟。在正常操作模式下,這個步驟將在步驟的初始化階段執行SQL,也就意味着它將優先於其他步驟執行。

你還可以啓用“Execute for each row?”選項來操作這個步驟,見圖16-12。(也就是說可以執行多個SQL在這個步驟裏面)

圖16-12:執行SQL語句的對話框

Blocking 步驟

另一個常見的用例是當你想在所有的記錄行到達某個步驟時執行一個操作。要做到這一點,你可以使用Blocking 步驟,見圖16-13

圖16-13:Blocking步驟

Blocking步驟在默認配置下是簡單的喫掉所有的記錄行。當所有的記錄行被喫掉後,它纔將最後一條記錄行傳遞給下一個步驟。這條記錄行將觸發隨後的步驟執行一個操作,這樣你就能確信所有其他的記錄行已經處理完了。

在上圖顯示的例子裏,SQL語句在所有的記錄行寫入了數據表後纔開始執行。

作業中的並行執行

作業中的作業項是按順序陸續執行的。這是默認的行爲,通常情況下你必須等待一個作業項執行完成之後纔開始執行另外一個。然而,我們在第2章中提到過,在一個作業裏面並行執行作業項也是有可能的。在並行執行作業項的用例下,作業項之後的多個作業項都是並行執行,而且是由不同的線程啓動的。

例如,如果你想並行的更新多張維表,你可以這樣做,見圖16-14。

圖16-14:並行更新多張維表

三、用Carte作爲子服務器

子服務器是在遠程服務器上執行轉換和作業的一個方便的組成模塊。Carte是一個輕量級的服務器進程,可以遠程監控和開啓轉換集羣的能力,這將在這一章節的下一部分講到。

子服務器是集羣的最小組成模塊。它是一個小型的HTTP服務器,用來接收遠程客戶端的命令,這些命令控制了子服務器上的作業和轉換的部署、管理和監控。

正如第3章描敘的,Carte程序可用於執行子服務器的功能,Carte也可以執行遠程的轉換和作業。[*8]

啓動一臺子服務器最簡單的方式,就是通過指定要運行(轉換和作業)的主機名或者IP地址,以及Web服務器的端口。例如,下面的命令將啓動一臺子服務器,在服務器server1的端口8181上

sh carte.sh server1 8181

配置文件

在kettle的早期版本里,是通過命令行指定配置選項。隨着配置選項數目的增加,kettle最近的版本依賴於子服務器上XML格式的配置文件,如果你有一個配置文件,你也能執行子服務器像這樣:

sh carte.sh slave-simple.xml

我們例子中的配置文件slave-simple.xml是些XML標籤塊,描敘了一臺子服務器的所有屬性,這裏是一個簡單的例子:

<slaveserver>標籤描敘了子服務器的主機名和子服務器應該監聽的端口,還可以可以配置子服務器的各個方面,一般情況下,這些選項可以優化服務器進程(如:Carte)的內存使用。

max_log_lines:設置這個選項,可以配置子服務器上的日誌系統保存在內存中的最大日誌行。要了解更多日誌系統信息可參看14章。

max_log_timeout_minutes:這個參數描敘了日誌行保存在內存中的最大時間(分鐘)。對於存活時間很長的轉換和作業,爲了防止子服務器內存溢出,這是一個尤其重要的選項。要了解更多可參看18章。

Object_timeout_minutes:默認情況下,在子服務器的狀態報告中,所有轉換和作業都是無期限保持可見的,這個參數可以自動的從狀態列表中清除老的作業。

定義子服務器

在轉換和作業中定義一個子服務器,你可以簡單的進入Spoon左邊的視圖部分。右擊“Slave server”樹形項目,選擇New. 然後填入一些子服務的具體信息,如圖16-15的例子.

圖16-15:定義子服務器

遠程執行

在Spoon中可以通過對話框“Execute a transformation”:指定要運行轉換和作業的子服務器。當子服務器被一個作業調用,它可通過在作業或者轉換作業項對話框中配置一個遠程子服務器,此時作業或者轉換作業項就可以遠程的執行了。[*9]

監視子服務器

這裏有幾種不同的方式遠程監控子服務器:

1、  Spoon: 在Spoon樹形菜單中右擊子服務器,選擇Monitor選項。這將在單獨的標籤中展現一個監控界面,包括了所有運行在子服務器上的轉換和作業的列表。

2、  Web瀏覽器: 打開一個瀏覽器窗口,輸入子服務器的地址,例如可以是http://server1:8181/.瀏覽器將顯示一個最基本但實用的子服務器菜單給你,使得你可以控制和監控子服務器

3、  PDI企業控制檯:它是Pentaho數據集成企業版的一部分,企業控制檯提供了監控和控制子服務器的能力。

4、  你的定製應用:每一個服務都被子服務器以XML格式的數據暴露。這些簡單的web服務可以讓你以方便且標準的方式與子服務器通信。如果你使用了Kettle的Java庫,還可以利用其解析XML的工具類。

Carte安全

默認情況Carte是使用簡單的HTTP認證,在文件pwd/kettle.pwd中定義了用戶名和密碼。Kettle默認附帶的用戶名/密碼都是cluster.

文件中的密碼可以利用kettle自帶的Encr工具來混淆。要生成一個Carte密碼文件,使用-carte選項,像這個例子:

sh  encr.sh –carte Password4Carte

OBF:1324324u432oj4324j3l2kj432j432lj43l2j43l2j43k24jc

使用文本編輯器,將返回的字符串追加到密碼文件中用戶名的後面

Someuser : OBF : 1324324u432oj4324j3l2kj432j432lj43l2j43l2j43k24jc

OBF:前綴告訴Carte這個字符串是被混淆了的,如果你不想混淆這個文件中的密碼,你可以清楚的指定密碼像這樣:

Someuser:Password4Carte

需要注意的是:密碼是被混淆了,而不是被加密了。這個算法僅僅是用來讓密碼識別起來更難,但絕對不是不可能。如果一個軟件有讀取這個密碼的能力,你必須假設別人也能讀取它[*10] ,因此,你應該總是給這個密碼文件添加一些合適的權限。如果你阻止了對這個文件的未授權的訪問,就首要的減少了某人能夠破解這個密碼的風險。

它也可以使用JAAS(Java Authentication and Authorization Service的簡稱)來配置Carte的安全。在這種情況下,你不得不定義2個系統配置(在文件kettle.properties中的例子):

  • loginmodulename: 登陸模塊使用的名字。
  • java.security.auth.login.config:這指向了需要被使用的這個JAAS配置文件。

這個JAAS用戶的名字是Kettle. 配置JAAS的具體細節超過了本書的範圍。更多的信息可以到JAAS的home page裏面可以找到http://java.sun.com/products/jaas/.

服務

子服務器給外部世界提供了一系列服務。 表格16-1列出了它定義的服務。 /kettle/ URI下的服務都駐留在嵌入的web服務器裏面[*11] 。 在我們的示例服務器裏面,就是http://server:8181/kettle/. 所有的服務都接受xml=Y選項,使得它返回的XML能夠被Kettle java類解析,使用的類(包 org.pentaho.di.www)也在表格16-1中提到了。

表格16-1:子服務器服務

服務名稱 描敘 參數 JAVA類
狀態 返回一個包含所有轉換和作業的摘要狀態
SlaveServerStatus
轉換狀態 檢索單個轉換的狀態並且列出所有步驟的狀態 Name(轉換的名稱);From line(啓動增量日誌記錄行[*12] ) SlaveServerTransStatus
準備執行 爲執行準備一個轉換,執行所有步驟的初始化 Name(轉換的名稱) WebResult
開始執行 開始執行步驟 Name(轉換的名稱) WebResult
啓動轉換 轉換的初始化和執行一次性開始。雖然方便,但是不適用在集羣執行環境下,因爲初始化需要在集羣上同時執行[*13] Name(轉換的名稱) WebResult
暫停轉換 暫停或者恢復一個轉換 Name(轉換的名稱) WebResult
停止轉換 終止一個轉換的執行 Name(轉換的名稱) WebResult
添加轉換 往子服務器中添加一個轉換,這需要一個客戶端提交XML形式的轉換給Carte
TransConfigurationWebResult
分配套接字 在子服務器上分配一個服務器套接字。請在本章閱讀“集羣轉換”後續部分獲取更多信息

嗅探步驟 獲取經過一個正在運行轉換步驟的記錄行 Trans(轉換的名稱);Step(步驟的名稱);Copy(步驟的複製數目);Lines(獲取的行數);Type(一個步驟輸入或輸出跳) <step-sniff> XML包含了一個RowMeta對象以及序列化的記錄行數據
啓動作業 開始執行作業 Name(作業的名稱) WebResult
停止作業 終止執行作業 Name(作業的名稱) WebResult
添加作業 往子服務器中添加一個作業。這需要客戶端提交XML的作業給Carte
JobConfigurationWebResult
作業狀態 獲取單個作業的轉換並列出所有作業項的狀態 Name(作業的名稱);From(啓動增量日誌記錄行)[*14]
註冊子服務器 註冊一個子服務器到主服務器上(參看“集羣轉換”部分)。這需要客戶端提交子服務器的XML給子服務器[*15]
SlaveServerDetectionWebResult(reply)
獲取子服務器 給一個所有子服務器的返回列表,爲主子服務器知道的
<SlaveServerDetections> XML標籤塊包括了SlaveServerDetection項目
添加導出 這個方法使得你可以以.zip歸檔格式傳輸一個可導出的作業活轉換通過子服務器。它在臨時文件中結束。這個客戶端提交zip文件的內容給Carte服務器。這個方法總是返回XML,因爲它沒有使用任何其他身份。
WebResult包含創建臨時文件的URL

四、集羣轉換

集羣技術可以用來水平擴展轉換,使得他們能夠同時運行在多臺服務器上。它將轉換的工作量均分到不同的服務器上。這一部分,我們將介紹怎樣配置和執行一個轉換,讓其運行在多臺機器上。

一個集羣schema由一臺主服務器,和一些子服務器組成,主服務器作爲一個集羣的控制器。簡單的說,我們提到的Carte控制服務器就是主服務器,其他的Carte服務器就是子服務器[*16] 。

一個集羣schema也包含元數據,記錄主服務器和子服務器之間怎樣來回傳遞的數據。在Carte服務器之間傳遞數據是通過TCP/IP套接字。數據交換之所以選擇TCP/IP,是因爲通過Web services比較慢,而且會引帶來不必要的開銷。

注意:在處理集羣schema的時候,理解主服務器和子服務器的概念非常重要。要想使得一臺子服務器變成主服務器,可簡單的在子服務器的複選框裏勾選上“Is the master?”。你不需要傳遞任何特別的選項給Carte.[*17]

定義一個集羣Schema

在你定義一個集羣schema之前,你需要定義一些子服務器。(參看本章先前的部分:定義一個子服務器。)一旦做到了這一點,你可以右擊“Kettle集羣schemas”樹形項目,然後選擇“新建”選項,如圖16-16顯示的。

你可以指定所有的細節給你的集羣schema。確保至少選擇一臺主服務器控制這個集羣和一臺或更多子服務器(見圖16-17).

圖16-16:創建一個新的集羣schema

圖16-17:“集羣schema”對話框

這裏是幾個重要的選項:

  • 端口:最小的TCP/IP socket端口被用來傳輸數據從一臺子服務器到另一臺。它僅僅是一個起始的端口。如果你的集羣轉換需要50個端口,就是端口號到端口號+50之間的所有端口都會被使用。
  • Sockets緩存大小:緩存大小用來緩解子服務器之間通信。不要將這個值設的太高,否則可能會引起數據傳輸處理的不良振盪。
  • Sockets刷新間隔(rows): 當數據記錄行到達這個值後,轉換引擎會在數據sockets上執行一個刷新,強制將數據推送到遠程子服務器, 設置這個參數值產生的性能影響,很大程度上依賴子服務器之間的網絡的速度和延遲。[*18]
  • Sokets數據是否壓縮?:決定子服務器之前傳輸的數據是否壓縮。在面對網絡相對慢時(例如10Mbps)這個非常好, 設成“Yes”將會導致集羣轉換變慢,因爲壓縮和解壓數據流需要附加的cpu時間。因此,通常情況下,在網絡不是瓶頸時,最好不啓用這個選項。
  • Dynamic cluster: 當啓用這個選項,將會使Kettle在主服務器上動態搜尋,來決定集羣schema的子服務器的列表。參看17章,可以獲取更多關於動態集羣的信息。

設計集羣轉換

要設計一個集羣轉換,得先建立一個標準的轉換,然後再將其變成集羣類型的。像先前那樣創建一個集羣schema,然後選擇你想要在子服務器上執行的步驟。右擊這個步驟,選擇你想要執行這個步驟的集羣。

例如, 你可能想從一個存儲在共享網絡驅動的大文件裏面讀取數據,排序數據,然後將數據寫入另外一個文件。如果你想在你的3個子服務器上並行的讀取和排序數據,圖16-18描敘了你怎麼樣來開始設計:

圖16-18:一個規則的轉換

下一步就是選取你想要在子服務器上執行的步驟,“CSV file input”和“Sort rows”步驟。選擇集羣…從這個步驟的上下文菜單裏面,選擇這個步驟要運行的集羣schema之後,你的轉換將變成如圖16-19顯示:

圖16-19:一個集羣轉換

當你執行這個轉換,所有的被定義成集羣運行(在圖16-19中那些有C×3)的步驟都將運行在這個子服務器上,而那些沒有集羣標識的步驟將運行在主服務器上。

注意: 在圖16-19中,記錄行是使用3個不同的子服務器的“Sort rows”步驟進行並行排序的,相同排序記錄的分組號的結果被送回給主服務器[*19] 。 由於Kettle讀取記錄行是從先前的步驟裏面,所以你不得不採取措施使得這些記錄有序,這個任務是由Sorted Merge步驟來執行的,它從所有的輸入步驟裏面一行一行的讀取記錄然後使得他們有序。 沒有這個步驟,並行排序將不會產生正確的結果。

轉換中至少要有一個步驟被指派運行在一個集羣上,這個轉換才認爲是一個集羣轉換。爲了調試和開發,集羣轉換可以使用Spoon中的執行對話框以非集羣的方法執行。

注意:在任何單獨的轉換裏面僅僅只能使用一個集羣,這點非常重要!

執行和監控

爲了運行一個集羣轉換,你可以有2個選擇。 一個選擇是通過在Spoon裏面選擇“Execute clustered”選項執行(如圖16-20):

圖16-20:從對話框“Execute a transformation”裏面執行一個集羣轉換

爲了調試的目的,你可以使用下面幾個集羣選項:

  • 提交轉換:提交生成的轉換給子服務器和主服務器。
  • 準備執行:執行在子服務器和主服務器上生成的轉換的初始化工作
  • 開始執行:當這個選項啓用,這個集羣轉換將在主服務器和字服務器上啓動。
  • 顯示轉換:在Spoon中打開主服務器和子服務器上的轉換,使得你可以看到生成的轉換。下一部分會提供更多子服務器和主服務器轉換信息。

請注意要完全的運行一個轉換,前三個選項必須啓用。第四個選項非必須,僅僅使你能夠看到這個生成的轉換.

另外一個運行集羣轉換的方法就是讓它作爲一個作業的轉換作業項運行。在那個作業項裏面,你可以啓用“Run this transformation in a clustered mode?”選項,使得這個轉換運行在一個集羣上(如圖16-21)

圖16-21:通過一個作業項來執行集羣轉換

元數據轉換

在主服務器和子服務器上僅僅運行同樣的轉換是不夠的,對於並行的數據處理需求,。那樣通常不是一個正確的方法。[*20] 主服務器和子服務器上執行的轉換是由一個叫做元數據轉換的翻譯流程產生的。 原始轉換的ETL元數據(在Spoon中設計的)被切分成片,重組,通過額外的信息加工,然後發送給目標子服務器。

對於元數據轉換,這裏有3種轉換類型:

  • 原始轉換:用戶在spoon中設計的集羣轉換。
  • 子服務器轉換:它源自原始轉換,運行在一個特定子服務器上的轉換,集羣裏的每個子服務器都會有一個子服務器轉換。
  • 主服務器轉換:它源自原始轉換,運行在主服務器上的轉換。

在圖16-19這個集羣例子裏面,3個子服務器轉換和一個主服務器轉換將被生成,圖16-22說明了主服務器轉換在我們的例子裏面是什麼樣的:

圖16-22:一個主服務器轉換

圖16-23說明了子服務器轉換是什麼樣的:

圖16-23:一個子服務器轉換

這個轉換淺灰色編號的區域指示了擁有遠程輸入或輸出連接的那些步驟(遠程步驟)。在我們的例子裏,有3個子服務器,每個子服務器發送數據從“Sort rows”到Sorted Merge步驟。這意味着3個“Sort rows”步驟都有一個遠程輸出步驟,並且Sorted Merge步驟有3個遠程輸入步驟。如果將鼠標懸置到這個淺灰色的矩形內,你將會獲取更多關於這個遠程步驟的信息,還有分配的端口號,如圖16-24:

圖16-24:遠程步驟上的提示信息

規則

你可以想象,當你操作這些元數據轉換時,這裏有很多可能性值得考慮。讓我們看看幾個普通在Kettle用來生成轉換時,確保邏輯操作正確的規則,[*21]

  • 如果一個步驟被配置成集羣運行,它會被複制到一個子服務器轉換。
  • 如果一個步驟沒有被配置成集羣運行,它會被複制到一個主服務器轉換。
  • 遠程輸出步驟(發送數據通過TCP/IP sockets)被定義給那些發送數據給一個集羣步驟的步驟。[*22]
  • 遠程輸入步驟(接受數據通過TCP/IP sockets)被定義給那些從一個集羣步驟接受數據的步驟。

接下來的規則更加複雜,因爲他們處理一些更加複雜的集羣方面:

  • 在多份複製情況下,集羣支持運行的步驟。[*23] 在這個例子裏,遠程輸入和輸出步驟是通過複製的編號進行分發的。對於這些遠程步驟投入更多的複製毫無意義。
  • 一般情況,爲了使得生成的轉換更可預測,Kettle集羣要求轉換儘量簡單。
  • 當一個步驟從特定的步驟裏面讀取數據(info-steps),Socket Reader和Socket Writer步驟被引進做這個轉換工作,圖16-25這個轉換正是這樣:


圖16-25:提供數據給集羣步驟

圖16-26:帶一個reader的子服務器轉換

圖16-27:主服務器分發數據給子服務器

仔細的人應該會發現,“Table input”步驟正在分發記錄行通過不同的socket writers傳輸數據給子服務器,這不是我們真正想看到的。在這種情形下,要確保拷貝數據到運行在遠程服務器上的多個複製(見圖16-28)[*24]

圖16-28:拷貝數據到子服務器

簡單地在子服務器上讀取數據三次是比較明智的,如圖16-29顯示。

圖16-29:在子服務器上獲取數據

數據流水線

記得在本章前面提到數據流水線或數據游泳通道:在Carte服務器之間交換數據越多 ,轉換就會越慢。理想情況下是,按照你能夠從頭到尾並行(執行)所有東西的方式組織你的數據。那樣的話,處理100個XML文件會比處理一個單一的大文件更容易,因爲多份文件情況下數據能夠被並行讀取。

作爲一個一般的規則,要使你的集羣轉換獲取好的性能:儘量讓轉換簡單,在同一子服務器上,儘可能在游泳通道里面做更多的事情,以減少服務器之間的數據傳輸。

五、分區

分區是一個非常籠統的術語,廣義的講是簡單拆分成多個部分。在數據集成和數據庫方面,分區指拆分數據表或者整個數據庫(分片)。表可以劃分成分區表,整個數據庫劃分成碎片

除此之外,使得文本或XML文件分區也是完全有可能的,例如(按)每家商店或區域(分)。由於數據集成工具需要支持各種技術,所以kettle中的分區被設計成與源數據和目標數據無關。

定義一個分區schema

分區是kettle轉換引擎的核心,每當分發記錄行通過若干目標步驟時,這就是在分割數據,這種情形下的分割規則猶如一個循環賽。實際上,這個規則並不比隨機分發好,它通常不是我們要提到的一個分區方法。

當我們談到Kettle中的分區,是指kettle可根據一個分區規則引導數據記錄行到某一個步驟複製的能力。在Kettle中,一組給定的分區集叫做分區schema,規則本身叫做分區方法。分區schema要麼包含一命名的分區列表,要麼簡單的包含數個分區。分區方法不是分區schema的一部分。

圖16-30提供了一個簡單的例子,定義了一個包含2個分區(A和B)的分區schema

圖16-30:“分區schema”對話框

一旦這個分區schema定義,在轉換裏,你可以根據一個分區方法應用它到一個步驟。  當你在這個步驟菜單上選擇分區選項時,會彈出一個對話框讓你選擇使用哪個分區方法(如圖16-31),分區方法可以是下面的一種:

  • None: 不使用分區,標準的“Distribute rows”或“Copy rows”規則被應用了[*25]
  • Mirror to all partitions: 在“數據庫分區”部分,我們再進行描敘這個特例。
  • Remainder of division:這個是kettle標準的分區方法。Kettle通過分區編號除以分區數目(一個整數或另外一種數據類型的校驗)[*26] ,產生的餘數被用來決定記錄行將發往哪個分區。例如在一個記錄行裏,如果你是有 “73” 標識的用戶身份,而且有3個分區定義,這樣這個記錄行屬於分區1,編號30屬於分區0, 編號14屬於分區2.
  • 通過插件實現分區方法:這個選項從分區方法對話框裏是不提供的。參看23章的一個分區插件例子,裏面有告訴更多關於寫插件的信息。

然後你需要指明使用哪個分區schema。例如你可選擇AB,如圖16-32.

在這一點上,一個詳細的對話框顯示,允許你爲這個分區方法指定參數。在我們的例子裏,我們需要指定基於它分區的字段(見圖16-33)。

圖16-31:選擇分區方法

圖16-32:選擇分區schema

圖16-33:指定基於它分區的字段

分區的目標

使用分區的目標是爲了提高轉換的並行度,大多數情況下,這根本不能達到,因爲這(僅僅通過分攤負載到多個複製或服務器上)不是並行的。

拿Group By步驟舉例;爲了簡單起見,我們使用Memory Group By步驟。如果你要利用標準的轉換記錄行分發,執行這個步驟的多份複製,幾乎可以肯定最終得不到正確的結果,因爲屬於某一個組的記錄可能在任意步驟複製裏結束。 彙總和會不正確,因爲步驟可能看到的不是所有的記錄行,僅僅是一個組的一部分。

讓我們思考一個簡單的例子,有一個包含客戶數據的文本文件,你想計算每個國際的郵政編碼數量(見圖16-34)

圖16-34:一個分區例子

文件讀取並且分區方法被應用到這個國家字段上。使用這種分區方法,可確保你總是發送數據記錄行對於同樣的國家到達同一步驟複製。這實際上使你在多份複製情況下,運行Memory Group By步驟並計算出正確的結果,此外這不是不可能的[*27]

另外一個分區的原因應該是你想並行的運行Database Lookup和Dimension Lookup/Update步驟。如果你在這些步驟上應用分區,有可能提高它的命中率。因爲你保證了一擁有同樣鍵的數據記錄行在同樣的步驟複製裏面結束,並且增加了值在內存中的可能性。

實施分區

在kettle裏面實施分區很簡單:對於每一個定義的分區,kettle會根據一個定義的分區方法啓動多個步驟複製。[*28] 也就是說如果定義5個分區,就會有5個步驟複製工作。分區步驟的前一步(圖16-34中的“Csv file input”步驟)是做重新分區。 當數據沒有被分區,並且要將它發送給一個分區步驟的時候,重新分區才執行。[*29] 使用一個分區schema分割數據並且在一跳上將其發送給使用另一個不同的分區schema,此時重新分區也會執行[*30] 。

內部變量

爲了使已經以分區格式存在的數據處理更加便捷,kettle定義了一些內部變量可幫助你:

  • ${Internal.Step.Partition.ID}: 這個變量描敘了步驟複製所屬分區的ID或名稱, 在一個分區格式裏面,可以用來讀取或寫入外部數據到Kettle.
  • ${Internal.Step.Partition.Number}:這個變量描敘了分區的編號從0到分區的數目減一。

例如,如果在N個文本文件中,數據已經被分區(文件-0到文件N,N是分區數目減一),你可以創建一個“Csv file input”步驟從文件名 file-${Internal.Step.Partition.Number}.csv中讀取數據,每一個步驟會僅僅讀取屬於它的分區數據。[*31]

數據庫分區

在Kettle的數據庫連接對話框中,可定義數據庫分區或碎片。當配置一個數據庫連接的時候,在Clustering標籤那可以定義,Kettle假定所有的分區都是同一數據庫和連接類型[*32] (見圖16-35)

圖16-35:定義數據庫分區

定義分區的目的是爲了從某一個分區甚至某一個物理數據庫讀取和寫入數據[*33] , 一旦在數據庫連接裏面定義了數據庫分區,你就基於這個信息創建了一個分區schema,你可以在“分區schema”對話框裏面使用“導入分區”按鈕(使用這個分區schema).

現在你可以在任何步驟裏面應用這個分區schema(就是說使用這個分區的數據庫連接)。Kettle將爲每個數據庫分區產生一個步驟複製,並且它將連接物理數據庫(數據庫分區和分區這個步驟的名字一樣)[*34] 。

圖16-36是在2個不同數據庫分區上並行執行一個查詢的例子,數據被流水到接下來的2個步驟複製計算某些東西

圖16-36:讀取數據庫分區

同樣的道理應用到所有數據庫步驟,可以保持數種數數據庫並行(處理)。這個“Mirror to all partitions”分區方法被特別設計成可並行的將同樣的數據寫入多種數據庫分區。對於查找數據表(需要在多個數據庫分區上覆制,不需要定義多個數據庫連接)[*35] 非常有用。

在集羣轉換中分區

在定義很多分區的情況下,步驟複製的數目會在轉換過程中急劇上升,解決這個問題則牽涉到在集羣轉換過程中將分區擴散到一系列的子服務器

在轉換執行期間,可用分區被平等的分配在可用的子服務器中間。如果你使用靜態的分區列表定義了一個分區schema,在運行時,那些分區將會被劃分到子服務器轉換的數量裏面[*36] 。Kettle這裏的限制是分區的數量等於或大於子服務器的數量,並且通常是均勻分佈於子服務器(slaves×2,slaves×3)。一個解決這個問題的簡單方式就是指明你要每臺子服務器動態配置的分區。[*37] 同先前的圖16-30一樣。

記住如果你在集羣轉換裏使用分區步驟,數據通過這些子服務器需要重新分區,,這會導致相當多的數據通訊。例如,如果你有10臺子服務器帶有10個步驟A的複製,並且接下來的步驟B運行在每臺具有3個分區的子服務器上,10×30個數據路徑需要創建,與圖16-7中的例子相似。 這些數據流向路徑中的10×30-30=270個由遠程步驟組成,會引起一些網絡阻塞,以及CPU和內存的消耗,在設計集羣和分區轉換的時候,請考慮這個影響。

總結

這一章,你看到了轉換中的多線程,集羣和分區,這裏有寫重點回顧:

  • 你學會了一個轉換怎樣並行的執行步驟,當步驟帶有多個步驟複製執行時,記錄行是怎樣被分發的,我們描敘了數據是怎樣被分發和合併到一起,並且介紹了幾個可能發生的經典問題。
  • 我們向您展示了在遠程服務器上,怎樣部署成可執行、管理和監控轉換和作業的子服務器[*38]
  • 深入的探討了多臺子服務器如何形成一個集羣,轉換怎樣利用這些子服務器資源。
  • 最後,你學到了在操作分組數據時,kettle分區是怎樣幫助你並行(執行)這些步驟,怎樣提高命中率的, 你也可以看到分區是怎樣應用到文本文件,怎樣使用分區變量和隔離的數據庫schema進行數據庫分區。

翻譯詞彙:

parallelizing 並行

pipelining流水線

row 記錄行

rows 記錄集

slave 子服務器

master 主服務器



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章