kettle 多表全刪全插同步數據 兩種方案

背景:

接到上級指示,要從外網某庫把數據全部導入到內網,數據每天更新一次即可,大約幾百萬條數據,兩個庫結構一樣,mysql的,兩台數據庫所在服務器都是windows server的,寫個java接口實現下吧,給了一個外網數據庫信息,好了,給你3天時間,開始搞吧。

分析:

用java接口寫邏輯?不好意思,基本沒思路,大神就不要噴我了。前公司的數據中台的數據都是通過kettle定時抽取的,雖然暫時我還不知道是個什麼鬼,但總比me思路強,於是果斷捨棄java接口,全面百度kettle,為了工作啊……

準備工作:

先不說抽取邏輯,咱得先把工具部署在自己電腦跑起來對吧,所以,準備下載部署開搞,不過好像kettle改名了,叫什麼pdi……
kettle下載部署,官網上我找了好長時間不知道咋下載免費的,所以找到了這個網站//sourceforge.net/projects/pentaho/files/Data%20Integration/ 我用的是7.1版本的,點擊7.1,把zip壓縮文件下載下來。
image
這個直接解壓就可以,無需安裝。
注意:1.先不急打開程序,kettle是純java編寫的,所以kettle工具的使用,必須要有java環境,盡量使用jdk1.8,因為別的版本我不確定會不會有問題,至於怎麼安裝jdk1.8和配置環境,請各位大佬自行百度。
2.根據百度經驗,還有點問題需要自行處理,就是數據庫的驅動包問題,因為我這隻涉及mysql所以也就只對mysql的驅動包進行操作,其他數據庫驅動連接是否有問題,不確定。
mysql官網驅動包下載地址://dev.mysql.com/downloads/connector/j/
image
點擊歷史版本,不要下最新版本或者比較高版本,為啥?因為不支持……
繼續操作
image
最高選用5.1.49版本,接上一話題,為啥不用再高版本,因為你可以下載下來對比下,5.1.49的解壓文件中,是有兩種jar包的,
image
帶bin的一定要有,沒有就連不上數據庫,5.1.49版本之後就沒有帶bin的了,不信你去看看。
把這兩種jar包直接放在以下路徑就好:
image

方案一:

在一個作業中使用多個轉換,效果圖:
image
當然這種方案的效果並不是都是這種的,但原理都是一樣的,有可能是所有的轉換是串行順序執行的,一條流程走完,那樣會造成其中某個轉換有問題,就不往後執行了,我這種雖然看着密集了些,但不會因為某個錶轉換出錯而停止。
接下來就是具體操作流程:

第一步:

創建轉換,點擊「文件」,點擊「新建」,點擊「轉換」,建立轉換空白頁
image

第二步:

配置來源庫和目標庫,如下:
image
image
因為要配置來源庫和目標庫,所以以上操作需要再重複一遍

第三步:

建立轉換邏輯腳本的內容:
表輸入:
image
雙擊表輸入:
image
點擊確定後,彈出:
image
我選的是,效果:
image
最後點擊確定即可;
使用插入/更新:為啥不用表輸出呢,因為表輸出沒法更新,還有主鍵的一些限制,所以用插入/更新,可以先用這個,不行你再百度其他的……,反正我用的還不錯。
image
image
一定要先建立上它倆之間的流程關係,再編輯插入/更新,否則,你在編輯插入/更新時,會在獲取字段和獲取映射關係時,沒有反應……
接下編輯插入/更新
image
然後保存轉換腳本,
image
我得是直接保存到桌面了,供演示用。
現在這一個轉換腳本就完成了,因為是多表同步數據,所以你要把第三步重複執行多邊,最後是一個數據庫表對應一個轉換文件,效果:
image
轉換文件的全路徑,盡量也是英文的,不要用中文的。

第四步:

建立定時作業任務,每天執行一遍數據抽取。
建立作業:
我參考了此篇博客://www.jianshu.com/p/bbc528a66b99
image
建立作業流程:
image
雙擊START按鈕:
image
重複要勾選上,否則只執行一次哦,然後根據需求,選擇定時類型,最後點擊確定即可。
雙擊轉換:
image
然後又是重複操作,再把一個轉換框拖到空白面板,然後設置好流程控制,然後編輯轉換,循環,最後就成了我一開始的效果圖了。
最後作業也要保存起來,會生成一個kjb文件,保存好。
image
點擊啟動按鈕,讓他自己執行就好了,窗口可以最小化,但是不能關閉!!!!!!!!!!!!!!!!!!!!!!!!
關閉就不定時執行了。

方案二:

如果是上百張表,那第一種方案就不行了,需要更為便捷的方法,所以我參考的帖子:
//www.cnblogs.com/dion-90/articles/8746184.html
//blog.csdn.net/qq_35318838/article/details/53322530
//www.freesion.com/article/3073451055/
以上文章,提供了具體思路和詳細操作步驟,但是我按照帖子來,卻怎麼也實現不了,一直報錯,解決不了,於是我就做了一下小改動,成功運行,數據也已經都抽取過來了,但spoon的詳細日誌裡邊會時不時的碰到一條數據插入有問題,主鍵衝突,是那張表的最後一條數據,不知道為何,還沒研究,總之這種方案目前能用,至於穩定性和準確性,因為我在線上用的第一種方案,所以我也沒法說好不好,各位大佬可以發揮一下……
好的,先上我得最終效果圖:
image
所以我們分步驟實現,最後整合到一起。

第一步:

獲取表名:
本質是一個轉換,所以,點擊「文件」,點擊「新建」,點擊「轉換」
然後進行下列操作:
image
image
image
然後三者之間建立流程關係:
image
配置轉換的數據庫配置,因為這個轉換的主要目的是獲取哪些數據庫表要進行數據同步,又因為我來源庫與目標庫數據庫結構都一樣,所以這個地方配置哪個庫是都可以的,各位如果有自己需求的話,自己根據實際情況選擇。
image
雙擊表輸入,進行編輯:
image
雙擊字段選擇,進行編輯:
image
複製記錄到結果,這個不用編輯。
然後保存這個轉換文件,改一下轉換名,方便記

第二步:

數據抽取:
建立一個轉換,點擊「文件」,點擊「新建」,選擇「轉換」
配置數據庫
image
建立邏輯:
image
image
雙擊表輸入:
image
雙擊表輸出:
image
兩個流程之間,建立流程關係,從表輸入到表輸出。
保存此轉換文件,命名自定義,方便即可。

第三步:

開始整合,建立一個作業,點擊「文件」,點擊「新建」,點擊「作業」:
然後,把作業的開頭建立
image
雙擊START,進行編輯:
image
獲取表名:
建立轉換,編輯轉換,建立流程控制
image
image
image
設置變量:
建立腳本,編輯腳本,建立流程控制
var prevRow=previous_result.getRows();
if (prevRow == null &&(prevRow.size()=0)){
false;
}else{
parent_job.setVariable(“tables”, prevRow);
parent_job.setVariable(“size”, prevRow.size());
parent_job.setVariable(“i”, 0);
parent_job.setVariable(“TABLENAME”, prevRow.get(0).getString(“tablename”,””));
true;
}

image
image
image
檢驗字段的值:
建立流程,編輯流程,建立流程控制
image
image
image
清除目標庫表數據:
本來這一步不是單獨的一步,看過之前我說的那幾篇參考博客就知道,這一步應該是嵌套在數據抽取那個轉換的,但我為什麼給單獨拿出來了呢,原因很簡單,就是我放在那裡邊,整體運行時報錯,想了一上午沒想明白,就另闢蹊徑,單獨做了一步,這樣就能整體運行了。
建立sql運行:
建sql腳本,編輯腳本,建立流程控制
truncate table ${TABLENAME}
image
image
image
抽取數據轉換:
建立轉換,編輯轉換,建立流程控制
image
image
image
判斷變量:
建立腳本,編輯腳本,建立流程控制
var list_Tables =parent_job.getVariable(“tables”).replace(” “,””).replace(“[“,””).replace(“]”,””).split(“,”);
var size = new Number(parent_job.getVariable(“size”));
var i = new Number(parent_job.getVariable(“i”))+1;
if(i<size){
parent_job.setVariable(“TABLENAME”, list_Tables[i]);
}
parent_job.setVariable(“i”,i);
true;
image
image
image
點擊確定即可
image
添加兩個分支,不知道幹啥的,這個隨意,我試過,不加也行……
image
可以改名,自定義的。
保存此作業,會生成一個kjb文件。
運行:
image
還是強調一遍,作業啟動之後,不要關窗口,否則就不執行了!!!!!!!!!!!!!!!!

結語:

以上就是多表數據同步的兩種方案,有不對的地方請指教,我也是萌新啊……

Tags: