背景:

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

分析:

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

準備工作:

先不說抽取邏輯,咱得先把工具部署在自己電腦跑起來對吧,所以,準備下載部署開搞,不過好像kettle改名了,叫什麼pdi……

kettle下載部署,官網上我找了好長時間不知道咋下載免費的,所以找到了這個網站https://sourceforge.net/projects/pentaho/files/Data%20Integration/ 我用的是7.1版本的,點選7.1,把zip壓縮檔案下載下來。



這個直接解壓就可以,無需安裝。

注意:1.先不急開啟程式,kettle是純java編寫的,所以kettle工具的使用,必須要有java環境,儘量使用jdk1.8,因為別的版本我不確定會不會有問題,至於怎麼安裝jdk1.8和配置環境,請各位大佬自行百度。

2.根據百度經驗,還有點問題需要自行處理,就是資料庫的驅動包問題,因為我這隻涉及mysql所以也就只對mysql的驅動包進行操作,其他資料庫驅動連線是否有問題,不確定。

mysql官網驅動包下載地址:https://dev.mysql.com/downloads/connector/j/



點選歷史版本,不要下最新版本或者比較高版本,為啥?因為不支援……

繼續操作



最高選用5.1.49版本,接上一話題,為啥不用再高版本,因為你可以下載下來對比下,5.1.49的解壓檔案中,是有兩種jar包的,



帶bin的一定要有,沒有就連不上資料庫,5.1.49版本之後就沒有帶bin的了,不信你去看看。

方案一:

在一個作業中使用多個轉換,效果圖:



當然這種方案的效果並不是都是這種的,但原理都是一樣的,有可能是所有的轉換是序列順序執行的,一條流程走完,那樣會造成其中某個轉換有問題,就不往後執行了,我這種雖然看著密集了些,但不會因為某個錶轉換出錯而停止。

接下來就是具體操作流程:

第一步:

建立轉換,點選“檔案”,點選“新建”,點選“轉換”,建立轉換空白頁

第二步:

配置來源庫和目標庫,如下:





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

第三步:

建立轉換邏輯指令碼的內容:

表輸入:



雙擊表輸入:



點選確定後,彈出:



我選的是,效果:



最後點選確定即可;

使用插入/更新:為啥不用表輸出呢,因為表輸出沒法更新,還有主鍵的一些限制,所以用插入/更新,可以先用這個,不行你再百度其他的……,反正我用的還不錯。





一定要先建立上它倆之間的流程關係,再編輯插入/更新,否則,你在編輯插入/更新時,會在獲取欄位和獲取對映關係時,沒有反應……

接下編輯插入/更新



然後儲存轉換指令碼,



我得是直接儲存到桌面了,供演示用。

現在這一個轉換指令碼就完成了,因為是多表同步資料,所以你要把第三步重複執行多邊,最後是一個數據庫表對應一個轉換檔案,效果:



轉換檔案的全路徑,儘量也是英文的,不要用中文的。

第四步:

建立定時作業任務,每天執行一遍資料抽取。

建立作業:

我參考了此篇部落格:https://www.jianshu.com/p/bbc528a66b99



建立作業流程:



雙擊START按鈕:



重複要勾選上,否則只執行一次哦,然後根據需求,選擇定時型別,最後點選確定即可。

雙擊轉換:



然後又是重複操作,再把一個轉換框拖到空白麵板,然後設定好流程控制,然後編輯轉換,迴圈,最後就成了我一開始的效果圖了。

最後作業也要儲存起來,會生成一個kjb檔案,儲存好。



點選啟動按鈕,讓他自己執行就好了,視窗可以最小化,但是不能關閉!!!!!!!!!!!!!!!!!!!!!!!!

關閉就不定時執行了。

方案二:

如果是上百張表,那第一種方案就不行了,需要更為便捷的方法,所以我參考的帖子:

https://www.cnblogs.com/dion-90/articles/8746184.html

https://blog.csdn.net/qq_35318838/article/details/53322530

https://www.freesion.com/article/3073451055/

以上文章,提供了具體思路和詳細操作步驟,但是我按照帖子來,卻怎麼也實現不了,一直報錯,解決不了,於是我就做了一下小改動,成功執行,資料也已經都抽取過來了,但spoon的詳細日誌裡邊會時不時的碰到一條資料插入有問題,主鍵衝突,是那張表的最後一條資料,不知道為何,還沒研究,總之這種方案目前能用,至於穩定性和準確性,因為我在線上用的第一種方案,所以我也沒法說好不好,各位大佬可以發揮一下……

好的,先上我得最終效果圖:



所以我們分步驟實現,最後整合到一起。

第一步:

獲取表名:

本質是一個轉換,所以,點選“檔案”,點選“新建”,點選“轉換”

然後進行下列操作:







然後三者之間建立流程關係:



配置轉換的資料庫配置,因為這個轉換的主要目的是獲取哪些資料庫表要進行資料同步,又因為我來源庫與目標庫資料庫結構都一樣,所以這個地方配置哪個庫是都可以的,各位如果有自己需求的話,自己根據實際情況選擇。



雙擊表輸入,進行編輯:



雙擊欄位選擇,進行編輯:



複製記錄到結果,這個不用編輯。

然後儲存這個轉換檔案,改一下轉換名,方便記

第二步:

資料抽取:

建立一個轉換,點選“檔案”,點選“新建”,選擇“轉換”

配置資料庫



建立邏輯:





雙擊表輸入:



雙擊表輸出:



兩個流程之間,建立流程關係,從表輸入到表輸出。

儲存此轉換檔案,命名自定義,方便即可。

第三步:

開始整合,建立一個作業,點選“檔案”,點選“新建”,點選“作業”:

然後,把作業的開頭建立



雙擊START,進行編輯:



獲取表名:

建立轉換,編輯轉換,建立流程控制







設定變數:

建立指令碼,編輯指令碼,建立流程控制

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;

}







檢驗欄位的值:

建立流程,編輯流程,建立流程控制







清除目標庫表資料:

本來這一步不是單獨的一步,看過之前我說的那幾篇參考部落格就知道,這一步應該是巢狀在資料抽取那個轉換的,但我為什麼給單獨拿出來了呢,原因很簡單,就是我放在那裡邊,整體執行時報錯,想了一上午沒想明白,就另闢蹊徑,單獨做了一步,這樣就能整體運行了。

建立sql執行:

建sql指令碼,編輯指令碼,建立流程控制

truncate table ${TABLENAME}







抽取資料轉換:

建立轉換,編輯轉換,建立流程控制







判斷變數:

建立指令碼,編輯指令碼,建立流程控制

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;







點選確定即可



新增兩個分支,不知道幹啥的,這個隨意,我試過,不加也行……



可以改名,自定義的。

儲存此作業,會生成一個kjb檔案。

執行:



還是強調一遍,作業啟動之後,不要關視窗,否則就不執行了!!!!!!!!!!!!!!!!

結語:

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