在生產環境中,我們經常會遇到數據定時同步的問題,這里整理出一個通用的FTP上傳同步的程序(FTP下載入庫的同步同理),供大家參考。本文以Windows環境為例進行日粒度同步數據。另外,本文所示例子,默認沒有使用資源庫。
一、實現的功能是什么?
定時從數據庫獲取時間范圍內的數據,然后將數據生成指定格式的文本文件,並將文件上傳到指定的FTP服務器上。
二、需要准備什么環境?
KETTLE運行環境;其他如通暢的網絡,數據庫信息,FTP信息,指定的文本格式,同步周期,均屬於需求范疇,不予贅述。
三、本程序的特點
1、可通過配置文件控制多節點采集(並行 or 串行皆可)
2、可補采已過日期的數據
3、可留存執行日志
4、可指定文件名稱和文本格式
四、程序概述
1、程序組成
包含一個入口腳本,兩個作業(Job),三個轉換(Transformation),三個文件夾(日志Logs,配置Configs,文件留存Files)。如下圖所示:
2、各組成的關系如下圖所示
3、配置文件說明
\Configs\Allconfigs.xml
各項解釋看注釋,修改配置文件filled和filled_date節點還可以進行補采數據。
踩過的坑:關於分隔符,低版本的KETTLE可能不支持一些特殊字符,比如歐元符號 “€”;嗯,數據量不是特別大的話替換字符即可,大數據可能有效率困擾。
<?xml version="1.0" encoding="utf-8" ?>
<root>
<type name ="ftp1">
<ftp>
<ftp_ip>127.0.0.1</ftp_ip>
<ftp_port>21</ftp_port>
<ftp_user>ftpuser</ftp_user>
<ftp_pass>ftpuser</ftp_pass>
<!--遠程路徑,ftp工具登錄后獲取的路徑,不是ftp站點的物理地址-->
<remote_filepath>/test</remote_filepath>
<!--本地文件路徑-->
<local_filepath>/Files</local_filepath>
</ftp>
<file>
<!--默認1,表示獲取的是昨天的數據;0表示獲取今天的數據;2表示獲取前天的數據;以此類推-->
<file_interval>1</file_interval>
<!--文件前綴-->
<file_ux>us_</file_ux>
<!--文件后綴-->
<file_dx>_dx</file_dx>
<!--字段分隔符-->
<file_split>,</file_split>
<!--文件擴展名:csv,txt,log等-->
<file_ex>csv</file_ex>
<!--文件中日期格式 比如 ux_yyyyMMdd_ex;此日期為采集的時間點-->
<file_dateset>yyyyMMddhh</file_dateset>
</file>
<fix>
<!--是否補采,默認0,其他表示需要補采,補采則使用filled_date作為日期-->
<filled>0</filled>
<!--如果補采,補采的日期是哪天,格式:yyyyMMddhhmmss-->
<filled_date></filled_date>
</fix>
</type>
</root>
4、讀取配置文件
GetConfigs.ktr
第一步讀取配置文件,這里我習慣設置了XML的配置文件。文件的配置如下所示,文件的全名稱來自命名參數CONFIGFILEFULLNAME,最終是由入口傳入的,這里使用變量方式調用。
第二步使用JS腳本對配置信息格式化,主要是處理文件名稱file_Name,采集時間first_result。
//Script here
Date.prototype.Format = function (fmt) { var o = { "M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小時
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
}; if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); return fmt; }; //文件名=前綴+日期+后綴+擴展名(生成文件時候添加)
var file_Name=file_ux+new Date().Format(file_dateset)+file_dx; var first_result=new Date(new Date().getTime()-file_interval*1000*3600*24).Format("yyyy-MM-dd 00:00:00"); if(filled!=0) {//如果補采,則取補采的時間點作為數據提取日期
first_result=filled_date; }
5、 設置配置信息為變量
SetVariable.ktr
其中設置變量如下圖所示。
6、獲取數據生成文件
OutputFileFromDB.ktr
其中表輸入如下圖所示,可以使用日期參數(FIRST_RESULT)對數據進行篩選。
文本文件輸出:
轉換文件所在的目錄:${Internal.Transformation.Filename.Directory}
7、單個節點的生成上傳
SignalJob.kjb
第二步設置變量:
第三步獲取數據生成文件:
第四步【FTP上傳】的配置如下兩圖所示。亦可修改代理,編碼,文件是否覆蓋等。
8、主作業
StartToFTP.kjb
第二步調用GetConfigs.ktr;
注意兩點,一個是在這個畫布里,右鍵-作業設置-命名參數,新增一個命名參數CONFIGFILEFULLNAME,可給默認值和描述;
二是在第三步子Job上右鍵-編輯作業入口-高級,勾選“對每個輸入行執行一次?”。
9、使用腳本后台運行主作業
Start.bat
腳本通過Kitchen.bat執行了StartToFTP的作業,並將執行日志輸出在\Logs\yyyyMMdd.log文件內。需要注意的是 /param,這里配置了一個命名參數CONFIGFILEFULLNAME,對應的是配置文件的全路徑。
@echo off rem ------------------KETTLE PATH SETTING------------------- set KettlePath=%KETTLE_HOME%\Kitchen.bat rem ------------------OTHER PATH SETTING-------------------- set JobPath=%cd%\StartToFTP.kjb set today=%date:~0,4%%date:~5,2%%date:~8,2% set LogFile=%cd%\Logs\%today%.log set paramValue=%cd%\Configs\Allconfigs.xml rem ------------------RUN JOB-------------------------------
%KettlePath% /file %JobPath% /param:CONFIGFILEFULLNAME=%paramValue% /level basic>>%LogFile%
五、拿到手后需要配置什么?
1、配置信息,如FTP,文本格式
\Configs\Allconfigs.xml
2、數據庫信息(使用資源庫則統一修改即可)
方法一: OutputFileFromDB.ktr文件第460行開始修改對應的server,database,username,password;
方法二: 使用KETTLE_HOME下的\spoon.bat打開OutputFileFromDB.ktr文件右鍵修改DB連接。
!注:建議方法二修改數據信息,方法一中的password需加密;
加密方式: "Encrypted " + Packages.org.pentaho.di.core.encryption.Encr.encryptPassword(password);對應的加密腳本:KETTLE_HOME下的\Encr.bat。
六、如何新增節點
提供串行和並行兩種多節點采集方式。
1、即先采集節點1再采集后續節點,優點是只有一個入口,一個調度作業;缺點是一旦某個節點不穩定,會造成后續節點采集失敗。
在\Configs\Allconfigs.xml里新增一組或多組type節點;如下所示。注意每組節點內子節點均一致,可對節點內容修改。
<?xml version="1.0" encoding="utf-8" ?>
<root>
<type name ="ftp1">
......
</type>
<type name ="ftp2">
...... </type>
......
</root>
2、可以配置多個節點單獨采集,優點是互不干擾,減少冗余;缺點是多個調度作業不便管理。
第一步:復制一份\Configs\Allconfigs.xml,比如命名為 \Configs\configs1.xml,修改各節點為新增內容;
第二步:復制一份Start.bat,比如命名為Start1.bat,修改Start1.bat中paramValue為新的配置文件名稱。
@echo off rem ------------------KETTLE PATH SETTING------------------- set KettlePath=%KETTLE_HOME%\Kitchen.bat rem ------------------OTHER PATH SETTING-------------------- set JobPath=%cd%\StartToFTP.kjb set today=%date:~0,4%%date:~5,2%%date:~8,2% set LogFile=%cd%\Logs\%today%.log set paramValue=%cd%\Configs\configs1.xml rem ------------------RUN JOB------------------------------- %KettlePath% /file %JobPath% /param:CONFIGFILEFULLNAME=%paramValue% /level basic>>%LogFile%
7、定時調度
Windows下可使用任務計划程序,Jenkins,其他調度平台。
8、程序獲取
https://github.com/missfoxw/kettle-SyncFTP
以上,歡迎交流修正。