PDI-KETTLE-4 使用Kettle完成通用DB生成指定文件并通过FTP上传
在生产环境中,我们经常会遇到数据定时同步的问题,这里整理出一个通用的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
以上,欢迎交流修正。