背景:公司的供应链系统中比较多的库需要用到数据同步以及数据备份、历史数据清理等场景。这些场景的实现大部分是通过开发手动编码进行数据处理,开发周期较长也教繁琐,故考虑使用一些数据迁移工具来做,目前使用的是Kettle。
Kettle是一个比较成熟的数据处理工具,通过图形化界面操作进行数据处理,然后再通过服务端执行ktr文件即可快速实现一个数据处理的过程。
准备:
下载社区版Kettle图形处理软件(用于生成ktr文件)
Pentaho Community Edition Download | Hitachi Vantara
注意是pdi-ce-xxx开头的zip文件(windows下载zip文件),下载之后解压即可
1、制作ktr文件(数据处理流程:以实现一个两个不同库的相同结构表的同步为例)
进入解压目录,双击Spoon.bat文件打开ktr图形操作界面
新建一个ktr转换文件并创建转换流程(具体的转换流程创建后面再补充)

创建之后保存文件(可以上传到S3服务或者其他FTP文件服务)
2、执行ktr文件
项目引入相关jar包
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-core</artifactId>
<version>9.2.0.0-290</version>
</dependency>
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-engine</artifactId>
<version>9.2.0.0-290</version>
</dependency>
<dependency>
<groupId>pentaho</groupId>
<artifactId>metastore</artifactId>
<version>9.2.0.0-290</version>
</dependency>
<dependency>
<groupId>org.pentaho</groupId>
<artifactId>pentaho-encryption-support</artifactId>
<version>9.2.0.0-290</version>
</dependency>
执行ktr文件进行转换
public boolean execute(InputStream ktr, Map<String, String> params) throws Exception {
try {
Map<String, String> kettleProperties = kettleConfigService.getCommonKettleProperties();
// 环境初始化
KettleEnvironment.init();
EnvUtil.environmentInit();
EnvUtil.applyKettleProperties(kettleProperties, true);
//构建转换器
TransMeta tm = new TransMeta(ktr, null, true, null, null);
Trans trans = new Trans(tm);
// 设置参数
if (params != null) {
for (Map.Entry<String, String> entry : params.entrySet()) {
trans.setParameterValue(entry.getKey(), entry.getValue());
}
}
// 执行转换
trans.execute(null);
// 等待转换结束
trans.waitUntilFinished();
//返回转换结果
if (trans.getErrors() > 0) {
log.info("ktr转换包含错误,ktr:{}", filename);
return false;
}
log.info("完成ktr转换,ktr:{}", filename);
return true;
} catch (Exception e) {
log.error("ktr转换异常,ktr:{}", filename, e);
return false;
}
}
job直接调用execute方法,传入ktr文件流(例如放到S3或其他FTP服务)即可直接执行数据转换
PS:一般创建流程文件时配置的数据库可能都是测试库,在服务器执行则需要使用生产数据库,可以通过如下代码动态指定执行时连接的数据库
TransMeta tm = new TransMeta(ktr, null, true, null, null);
// 替换使用到的数据库为生产库
for (DatabaseMeta dm : tm.getDatabases()) {
dm.setHostname("${xx.host_name}");
dm.setDBName("${xx.db_name}");
dm.setDBPort("${xx.db_port}");
dm.setUsername("${xx.username}");
dm.setPassword("${xx.password}");
}
667

被折叠的 条评论
为什么被折叠?



