ETL_Kettle

简介

介绍

1、ETL是数据抽取、转换、加载
2、Spoon是图形界面接口
3、Kettle包含job和transformation两种脚本
4、Kettle依赖java环境运行

目录文件

Carte.bat/sh :启动集群命令
Encr.bat/sh :加密算法
Import.bat/sh :导入命令
Kitchen.bat/sh :运行job的命令
Pan.bat/sh :运行transformation的命令
set-pentaho-en.bat/sh :设置环境变量脚本
Spoon.bat/sh :启动Kettle UI操作界面

核心概率

1、转换处理抽取、转换、加载各种对数据行的操作
2、转换包含一个或多个步骤(step)命名需唯一,如读取文件、过滤数据行、数据清洗或将数据加载到数据库
3、转换里的步骤通过跳(hop)来连接,行集的数据行缓存
4、数据行-数据类型,String/Number/Integer/BigNumber(任意精度)/Date/Boolean/Binary(二进制文件)
5、数据行-元数据,每个步骤输出数据行有对字段的描述也就是元数据

文件类型

1、XML-XPath

XPath-路径表达式
books  选取books元素的所有子节点
/books	选取根元素books
books/book	选取books的子元素的所有book元素
//book	选取book子元素,而不管它们在文档中的位置
books//book	 选取属于books元素的后代的所有book元素,而不管它们位于books之下的什么位置
//@lang  选取名为lang 的所有属性

2、JSON-JSONPath
方法:点记法;括号记法
点记法(常用)示例:$.store.book[0].title --查询store、book数组下key为title的所有值

$	查询的根节点对象,用于表示一个json数据,可以是数组或对象
@	过滤器断言处理的当前节点对象
*	通配符,可以表示一个名字或数字
..  递归搜索
.<name>   表示一个子节点
['<name>'(,'<name>')]   表示一个或多个子节点
[<name>(,<name>)]   表示一个或多个数组下标
[start:end]    数组片段,区间为[start,end],不包含end
[?(<expression>)]    过滤器表达式,表达式结果必须为boolean

操作 - 转换

多文件合并

1、分析:
输入:Excel输入;输出:Excel输出
2、步骤:
Excel输入–选择文件目录(D:\input\)–通配符号(测试文件.*.xlsx)–包含子目录(是)

备注:
多个文件需要满足相同格式

输入

文本、表格、自定义常量(放在开始供后面节点使用)等输入

输出

表格、SQL等输出

转换

1、Concat fields
将多个字段连接起来形成一个新的字段

2、值映射
把字段的一个值映射成其他的值

3、增加常量
在本身的数据流里面添加一列数据,该列的数据都是相同的值

4、增加序列
给数据流添加一个序列字段

5、字段选择
从数据流中选择字段、改变名称、修改数据类型

6、计算器
一个函数集合来创建新的字段,还可以设置字段是否移除(临时字段)

7、剪切字符串
指定输入流字段裁剪的位置剪切出新的字段

8、字符串替换
指定搜索内容和替换内容,如果输入流的字段匹配上搜索内容就进行替换生成新字段

9、字符串操作
去除字符串两端空格和大小写切换,并生成新的字段

10、排序记录
按照指定的字段的升序或降序对数据流排序

11、去除重复记录
去除数据流里面相同的数据行,通过指定用来比较的字段(注意:必须对数据流进行排序)

12、唯一行(哈希值)
唯一行就是删除数据流重复的行(效率高)(注意:其实现的原理跟去除重复记录不同)

13、拆分字段
把字段按照分隔符拆分成两个或多个字段(注意:拆分字段后,原字段就不存在于数据流中)

14、列拆分为多行
把指定分隔符的 进行拆分为多行

15、列转行
如果数据一列有相同的值,按照指定的字段,把多行数据转换为一行数据(注意:必须对数据流进行排序)
指定关键字段(原数据流列转换的字段)、分组字段(相同值的字段),目标字段(转换后流字段),数据字段(转换后流字段对应值的原数据流字段),关键字值(原数据流列转换的字段值)

16、行转列
把数据字段的字段名转换为一列,把数据行变成数据列
指定key字段、字段名称、key值、value字段

17、行扁平化
把同一组的多行数据合并成一行
注意:只有数据流的同类数据数据行记录一致的情况才可使用;数据流必须进行排序

转换

1、替换NULL值
把null转换为其它的值
指定字段进行null替换

2、写日志
在调试的时候使用,把日志信息打印到日志窗口

流程

1、Switch/case
让数据流从一路到多路
一般通过Switch/case,让数据流进行拆分到多个输出

2、过滤记录
让数据流从一路到两路,true-false

3、空操作
空操作一般作为数据流的终点,什么都不做

4、中止
中止是数据流的终点,如果有数据了到这里,将会报错并中止后续操作
一般用于校验数据

查询

1、HTTP client
使用GET的方式提交请求,获取返回的页面内容
步骤:
自定义常量(url)— HTTP client — Get data from XML — Excel输出

2、数据库查询(同一个库)
就是数据库里面的左连接
两张表执行左关联查询,把左边的表数据全部查询出来
步骤:
表输入 — 数据库查询 — Excel输出

3、数据库连接(不同库)
可以执行两个数据库的查询,和单参数的表输入
表输入 — 数据库连接(编写查询语句,通过?匹配表输入指定的字段) — Excel输出

4、流查询
在查询前把数据库都加载 内存中,并且只能进行等值查询

连接

1、合并记录
将两个不同来源的数据合并,这两个来源的数据分别为旧数据和新数据,该步骤将旧数据和新数据按照指定的关键字匹配、比较、合并
注意:
旧数据和新数据需要事先按照关键字排序;
旧数据和新数据要有相同的字段名称;

合并记录后,会对新旧数据进行比较,并得到新记录数据流并多了一个flagfield字段标识(identical-相同、changed-发送变化、new-新数据中增加的记录、deleted-新数据中被删除的记录)

2、记录关联(笛卡尔积)
对两个数据流进行笛卡尔积操作

3、记录集连接
类似于数据库中的左连接、右连接、内连接、外连接
注意:需要提前对数据流进行排序记录

统计

1、分组
指按照某一个或某几个进行分组,同时可以将其余字段按照某种规则进行合并
注意:需要提前对数据流进行排序记录

映射

1、映射(子转换)
用来配置子转换,对子转换进行调用的一个步骤,可以理解为子转换的封装步骤
映射(映射输入规范 — 数据库查询 — 映射输出规范)

如:映射输入规范指定字段,在数据库查询中通过该字段查询到指定字段记录输出

脚本

1、Java代码
在Common use — Main 下编写代码

Excel输入 — Java代码 — Excel输出
示例:

//获取输入流中的code字段值
String code = get(Fields.In,"code").getString(r);
//如果code为空,为空设置为name的值,不为空code值后面加0
if(code == null || "".equals(code)){
	code = get(Fields.In,"name").getString(r);
}else{
	code += "0";
}
//设置code的值
get(Fields.Out,"newcode").setValue(r.code);
//新的字段需要在下面定义好类型

2、执行SQL脚本
可以执行一个update语句,用来更新某表中的数据

表输入(指定输出id字段) — 执行SQL脚本(根据获取的id进行脚本执行)
update t_user set status = 1 where id = ?

操作 - 作业

参数

1、全局参数
作用于所有转换,在当前用户.kettle文件夹中的kettle.properties文件中定义
使用方式:方式一 %%变量名%% 方式二 ${变量名}
注意:配置全局参数,需要重启才能生效;
在SQL中使用变量,需要勾选“是否替换变量”选项;

2、局部参数
通过Set Variables 与 Get Variables方式设置
使用方式:方式一 %%变量名%% 方式二 ${变量名}
注:Set Variables 作用于下一步骤使用

3、自定义常量数据
自定义常量变量名和类型,并设置对应值,在表输入的SQL语句中使用?来替换,其先后顺序根据常量定义的顺序
注意:需要指定从步骤输入数据选项

4、转换命名参数
在转换内部定义的变量,作用于转换内部
使用方式:${变量名}
在转换空白处右键 — 转换设置

设置变量/获取变量

获取变量,需要在作业中的下一步骤中使用
如:在一个转换中添加了设置变量,下一步转换中的第一个步骤是获取变量(使用?)

09:45:47.991 [Thread-28] INFO c.r.k.s.i.KettleJobServiceImpl - [runJobRightNow,281] - jobName,D:/kettle/workspace/调试/base_etl_online/etl_plasma_out.kjb 09:45:47.999 [http-nio-8888-exec-20] DEBUG c.r.k.m.K.selectKettleJobList - [debug,135] - <== Total: 5 09:45:48.005 [schedule-pool-1] DEBUG c.r.s.m.S.insertOperlog - [debug,135] - <== Updates: 1 09:45:48.204 [Thread-34] INFO c.r.k.t.KettleUtil - [runKettleJob,276] - Starting job [etl_plasma_out_job] with log channel ID: ccf52a19-00d5-48c4-8804-cecd216d57af 09:45:48.205 [Thread-34] INFO c.r.k.t.KettleUtil - [runKettleJob,283] - 运行作业[etl_plasma_out_job]携带参数={"SCHEDULEINO":"122"} 09:45:48.207 [Thread-34] INFO c.r.k.l.XLogListener - [addLogListener,241] - 任务etl_plasma_out_job日志监听启动了,日志路径D:\kettle\logs... 09:45:48.210 [Thread-34] INFO c.r.k.t.KettleUtil - [runKettleJob,296] - 运行作业[etl_plasma_out_job]携带LogChannelId=ccf52a19-00d5-48c4-8804-cecd216d57af 2025/07/29 09:45:48 - etl_plasma_out_job - 开始执行任务 09:45:48.214 [Thread-47] WARN o.pentaho.di.job.Job - [logToLogger,92] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] 开始执行任务 2025/07/29 09:45:48 - etl_plasma_out_job - 开始项[浆站编号入参] 09:45:48.502 [Thread-47] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] 开始项[浆站编号入参] 2025/07/29 09:45:48 - 自定义日志输出 - 传入参数:'122' 09:45:48.629 [Thread-47] DEBUG c.r.k.l.XLogListener - [eventAdded,231] - 因为异常丢失的日志{"timeStamp":1753753548626,"level":"MINIMAL","message":{"logChannelId":"0b269c6b-b25d-4329-947f-2e9588dcd34c","level":"MINIMAL","subject":"自定义日志输出","error":false,"message":"传入参数:'122'"}} 2025/07/29 09:45:48 - etl_plasma_out_job - 开始项[调度任务] 09:45:48.630 [Thread-47] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] 开始项[调度任务] 2025/07/29 09:45:48 - 调度任务 - Using run configuration [Pentaho local] 09:45:48.808 [Thread-47] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] Using run configuration [Pentaho local] 2025/07/29 09:45:48 - 调度任务 - Using legacy execution engine 09:45:48.861 [Thread-47] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] Using legacy execution engine 2025/07/29 09:45:48 - 调度任务初始化 - 为了转换解除补丁开始 [调度任务初始化] 09:45:48.913 [Thread-47] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online/t_etl_scheduler_online.ktr] 为了转换解除补丁开始 [调度任务初始化] Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary. 2025/07/29 09:45:49 - 调度任务选择.0 - Finished reading query, closing connection. 09:45:49.508 [调度任务初始化 - 调度任务选择] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online/t_etl_scheduler_online.ktr] Finished reading query, closing connection. 2025/07/29 09:45:49 - 设置正在调用任务.0 - Setting environment variables... 09:45:49.511 [调度任务初始化 - 设置正在调用任务] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online/t_etl_scheduler_online.ktr] Setting environment variables... 2025/07/29 09:45:49 - 设置正在调用任务.0 - Set variable STATIONID to value [122] 09:45:49.562 [调度任务初始化 - 设置正在调用任务] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online/t_etl_scheduler_online.ktr] Set variable STATIONID to value [122] 2025/07/29 09:45:49 - 调度任务选择.0 - 完成处理 (I=1, O=0, R=0, W=1, U=0, E=0) 09:45:49.568 [调度任务初始化 - 调度任务选择] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online/t_etl_scheduler_online.ktr] 完成处理 (I=1, O=0, R=0, W=1, U=0, E=0) 2025/07/29 09:45:49 - 设置正在调用任务.0 - Set variable BASE_BIMS to value [BASE_BIMS_122] 09:45:49.615 [调度任务初始化 - 设置正在调用任务] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online/t_etl_scheduler_online.ktr] Set variable BASE_BIMS to value [BASE_BIMS_122] 2025/07/29 09:45:49 - 设置正在调用任务.0 - Finished after 1 rows. 09:45:49.670 [调度任务初始化 - 设置正在调用任务] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online/t_etl_scheduler_online.ktr] Finished after 1 rows. 2025/07/29 09:45:49 - 设置正在调用任务.0 - 完成处理 (I=0, O=0, R=1, W=1, U=0, E=0) 09:45:49.720 [调度任务初始化 - 设置正在调用任务] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online/t_etl_scheduler_online.ktr] 完成处理 (I=0, O=0, R=1, W=1, U=0, E=0) 2025/07/29 09:45:49 - etl_plasma_out_job - 开始项[获取出库日期] 09:45:49.772 [Thread-47] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] 开始项[获取出库日期] 2025/07/29 09:45:49 - 获取出库日期 - Using run configuration [Pentaho local] 09:45:49.827 [Thread-47] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] Using run configuration [Pentaho local] 2025/07/29 09:45:49 - 获取出库日期 - Using legacy execution engine 09:45:49.879 [Thread-47] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] Using legacy execution engine 2025/07/29 09:45:49 - get_plasma_outdate - 为了转换解除补丁开始 [get_plasma_outdate] 09:45:49.929 [Thread-47] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online\base_plasma_out\get_plasma_outdate.ktr] 为了转换解除补丁开始 [get_plasma_outdate] 2025/07/29 09:45:50 - 出库日期.0 - Finished reading query, closing connection. 2025/07/29 09:45:50 - 设置出库日期变量.0 - Setting environment variables... 09:45:50.161 [get_plasma_outdate - 出库日期] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online\base_plasma_out\get_plasma_outdate.ktr] Finished reading query, closing connection. 09:45:50.161 [get_plasma_outdate - 设置出库日期变量] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online\base_plasma_out\get_plasma_outdate.ktr] Setting environment variables... 2025/07/29 09:45:50 - 设置出库日期变量.0 - Set variable plasmaOutDate to value [20250729] 09:45:50.212 [get_plasma_outdate - 设置出库日期变量] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online\base_plasma_out\get_plasma_outdate.ktr] Set variable plasmaOutDate to value [20250729] 2025/07/29 09:45:50 - 出库日期.0 - 完成处理 (I=1, O=0, R=0, W=1, U=0, E=0) 09:45:50.219 [get_plasma_outdate - 出库日期] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online\base_plasma_out\get_plasma_outdate.ktr] 完成处理 (I=1, O=0, R=0, W=1, U=0, E=0) 2025/07/29 09:45:50 - 设置出库日期变量.0 - Finished after 1 rows. 09:45:50.267 [get_plasma_outdate - 设置出库日期变量] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online\base_plasma_out\get_plasma_outdate.ktr] Finished after 1 rows. 2025/07/29 09:45:50 - 设置出库日期变量.0 - 完成处理 (I=0, O=0, R=1, W=1, U=0, E=0) 09:45:50.318 [get_plasma_outdate - 设置出库日期变量] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online\base_plasma_out\get_plasma_outdate.ktr] 完成处理 (I=0, O=0, R=1, W=1, U=0, E=0) 2025/07/29 09:45:50 - etl_plasma_out_job - 开始项[血浆出库] 09:45:50.371 [Thread-47] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] 开始项[血浆出库] 2025/07/29 09:45:50 - 血浆出库 - Using run configuration [Pentaho local] 09:45:50.433 [Thread-47] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] Using run configuration [Pentaho local] 2025/07/29 09:45:50 - plasma_out - 开始项[厂家浆员档案] 09:45:50.487 [plasma_out UUID: 12b11642-8e6e-4337-905c-07aba5c798e7] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online\base_plasma_out\etl_plasma_out\etl_plasma_out.kjb] 开始项[厂家浆员档案] 2025/07/29 09:45:50 - 厂家浆员档案 - Using run configuration [Pentaho local] 09:45:50.549 [plasma_out UUID: 12b11642-8e6e-4337-905c-07aba5c798e7] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online\base_plasma_out\etl_plasma_out\etl_plasma_out.kjb] Using run configuration [Pentaho local] 2025/07/29 09:45:50 - 厂家浆员档案 - Using legacy execution engine 09:45:50.600 [plasma_out UUID: 12b11642-8e6e-4337-905c-07aba5c798e7] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online\base_plasma_out\etl_plasma_out\etl_plasma_out.kjb] Using legacy execution engine 2025/07/29 09:45:50 - set_factory_donor - 为了转换解除补丁开始 [set_factory_donor] 09:45:50.650 [plasma_out UUID: 12b11642-8e6e-4337-905c-07aba5c798e7] INFO o.p.di.trans.Trans - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online\base_plasma_out\etl_plasma_out\etl_plasma_out.kjb file:///D:/kettle/workspace/调试/base_etl_online/base_plasma_out/etl_plasma_out/set_factory_donor.ktr] 为了转换解除补丁开始 [set_factory_donor] 09:45:51.031 [Thread-28] INFO c.r.k.t.KettleUtil - [runKettleJob,276] - Starting job [etl_plasma_out_job] with log channel ID: ccf52a19-00d5-48c4-8804-cecd216d57af 09:45:51.031 [Thread-28] INFO c.r.k.t.KettleUtil - [runKettleJob,283] - 运行作业[etl_plasma_out_job]携带参数={"SCHEDULEINO":"123"} 09:45:51.031 [Thread-28] INFO c.r.k.l.XLogListener - [addLogListener,241] - 任务etl_plasma_out_job日志监听启动了,日志路径D:\kettle\logs... 09:45:51.033 [Thread-28] INFO c.r.k.t.KettleUtil - [runKettleJob,296] - 运行作业[etl_plasma_out_job]携带LogChannelId=ccf52a19-00d5-48c4-8804-cecd216d57af 2025/07/29 09:45:51 - etl_plasma_out_job - 开始执行任务 09:45:51.033 [Thread-65] WARN o.pentaho.di.job.Job - [logToLogger,92] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] 开始执行任务 2025/07/29 09:45:51 - etl_plasma_out_job - 开始项[浆站编号入参] 09:45:51.301 [Thread-65] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] 开始项[浆站编号入参] 2025/07/29 09:45:51 - 自定义日志输出 - 传入参数:'123' 09:45:51.408 [Thread-65] DEBUG c.r.k.l.XLogListener - [eventAdded,231] - 因为异常丢失的日志{"timeStamp":1753753551408,"level":"MINIMAL","message":{"logChannelId":"0b269c6b-b25d-4329-947f-2e9588dcd34c","level":"MINIMAL","subject":"自定义日志输出","error":false,"message":"传入参数:'123'"}} 09:45:51.408 [Thread-65] DEBUG c.r.k.l.XLogListener - [eventAdded,231] - 因为异常丢失的日志{"timeStamp":1753753551408,"level":"MINIMAL","message":{"logChannelId":"0b269c6b-b25d-4329-947f-2e9588dcd34c","level":"MINIMAL","subject":"自定义日志输出","error":false,"message":"传入参数:'123'"}} 2025/07/29 09:45:51 - etl_plasma_out_job - 开始项[调度任务] 09:45:51.409 [Thread-65] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] 开始项[调度任务] 2025/07/29 09:45:51 - 调度任务 - Using run configuration [Pentaho local] 09:45:51.517 [Thread-65] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] Using run configuration [Pentaho local] 2025/07/29 09:45:51 - 调度任务 - Using legacy execution engine 09:45:51.617 [Thread-65] INFO o.pentaho.di.job.Job - [logToLogger,96] - [D:\kettle\workspace\调试\base_etl_online\etl_plasma_out.kjb] Using legacy execution engine 传递的参数不同,为什么携带LogChannelId=ccf52a19-00d5-48c4-8804-cecd216d57af一样,怎么解决
最新发布
07-30
<think>我们面对的问题:在Kettle Java代码中调用Job时,即使传递不同参数,生成的logChannelId相同,需要确保每次执行生成唯一的logChannelId以区分日志。 分析: 根据Kettle的日志机制,每个作业或转换在执行时都会生成一个唯一的日志通道ID(logChannelId),用于在日志系统中跟踪特定执行实例。如果发现多次执行使用相同的logChannelId,可能是由于某些原因导致日志通道没有被正确重置或创建。 解决思路: 1. 确保每次执行作业前,都创建一个新的日志通道。 2. 在Kettle的API中,我们可以通过设置日志通道ID来区分不同的执行实例。 具体步骤: 根据引用[3]中提供的Java代码示例,我们可以在调用作业之前,手动设置一个唯一的日志通道ID。 参考Kettle API,我们可以使用`LogChannel`类来创建新的日志通道。但是,在调用作业时,通常是通过`Job`类的`start`方法执行。我们需要在启动作业前为作业设置一个新的日志通道。 代码示例: ```java import org.pentaho.di.core.logging.KettleLogStore; import org.pentaho.di.core.logging.LogChannel; import org.pentaho.di.job.Job; import org.pentaho.di.job.JobMeta; public void runJobWithUniqueLogChannel(JobMeta jobMeta, Map<String, String> parameters) throws Exception { // 创建一个新的日志通道,并为其生成一个唯一的ID LogChannel logChannel = new LogChannel(jobMeta); // 获取新创建的日志通道ID String logChannelId = logChannel.getLogChannelId(); // 创建作业对象,并将新的日志通道设置给作业 Job job = new Job(null, jobMeta); job.setLogChannel(logChannel); // 设置参数 for (Map.Entry<String, String> entry : parameters.entrySet()) { job.setParameterValue(entry.getKey(), entry.getValue()); } // 启动作业 job.start(); job.waitUntilFinished(); // 可选的:在作业完成后,我们可以从日志存储中获取该通道的日志 String logText = KettleLogStore.getAppender().getBuffer(logChannelId, false).toString(); System.out.println(logText); } ``` 说明: - 我们通过`LogChannel`构造函数创建了一个新的日志通道,这个通道会自动生成一个唯一的ID。 - 然后,我们将这个日志通道设置给新创建的作业对象(通过`job.setLogChannel(logChannel)`)。 - 这样,该作业在执行过程中产生的所有日志都会关联到这个唯一的日志通道ID。 注意事项: 1. 确保在每次执行作业时都创建一个新的`LogChannel`实例,这样每次都会生成新的唯一ID。 2. 在作业执行完成后,如果需要获取日志,可以通过`KettleLogStore`获取该通道的日志。 另外,根据引用[1]中提到的命令行执行方式,我们注意到在命令行中执行作业时,每次执行都会生成新的日志通道。因此,在Java代码中模拟这种方式,就是每次执行都创建一个新的作业实例,并为其设置新的日志通道。 如果上述方法不能解决问题,可能需要检查Kettle的版本,因为某些旧版本可能存在日志通道复用的bug。建议升级到最新版本。 相关问题: 1. 如何在Kettle中自定义日志输出? 2. Kettle作业的并发执行如何避免日志混淆? 3. 如何将Kettle的日志输出到不同的文件中? 以上解决方案基于Kettle的API,通过为每次作业执行创建新的日志通道来确保日志通道ID的唯一性。</think>### Kettle日志通道ID唯一性解决方案 在Kettle中,当通过Java代码调用作业时,若出现不同参数传递后日志通道ID(logChannelId)相同的问题,这通常是由于日志通道未正确重置或复用导致的。以下是确保每次执行生成唯一logChannelId的完整解决方案: #### 核心解决步骤 1. **创建新的日志通道** 在每次执行作业前,显式创建新的日志通道: ```java LogChannel logChannel = new LogChannel("自定义通道名称"); String logChannelId = logChannel.getLogChannelId(); // 获取唯一ID ``` 2. **关联作业与日志通道** 将新创建的日志通道绑定到作业实例: ```java Job job = new Job(repository, jobMeta); job.setLogChannel(logChannel); // 关键步骤:绑定唯一通道 ``` 3. **参数传递与执行** 使用Kettle变量系统传递参数: ```java job.setVariable("参数名", "参数值"); // 设置作业级变量 job.start(); // 启动作业 ``` #### 完整示例代码 ```java import org.pentaho.di.core.logging.LogChannel; import org.pentaho.di.job.Job; import org.pentaho.di.job.JobMeta; public void executeJobWithUniqueLog(String jobPath, Map<String,String> params) { try { // 1. 创建唯一日志通道 LogChannel log = new LogChannel("JOB_EXEC_" + System.currentTimeMillis()); // 2. 加载作业元数据 JobMeta jobMeta = new JobMeta(jobPath, null); // 3. 创建作业实例并绑定日志通道 Job job = new Job(null, jobMeta); job.setLogChannel(log); // 关键绑定 // 4. 设置参数 params.forEach((k,v) -> job.setVariable(k, v)); // 5. 执行并获取唯一ID job.start(); String logChannelId = job.getLogChannelId(); System.out.println("唯一日志通道ID: " + logChannelId); } catch (Exception e) { e.printStackTrace(); } } ``` #### 关键机制说明 1. **日志通道生命周期** 每个`LogChannel`实例自动生成唯一ID(UUID格式),通过`new LogChannel()`确保每次执行都创建新实例[^3]。 2. **变量作用域** 使用`setVariable()`设置的参数存在于作业执行上下文,不会影响日志通道ID生成。 3. **并发处理** 在多线程环境中,为每个线程创建独立的`LogChannel`实例可避免ID冲突。 #### 验证方法 在作业中添加日志输出步骤: ```java // 在作业的Java代码步骤中添加 logBasic("当前通道ID: " + getLogChannelId()); ``` 检查每次执行输出的通道ID是否不同。 #### 注意事项 1. 避免复用`Job`对象,每次执行都创建新实例 2. 使用`System.currentTimeMillis()`或`UUID`作为日志通道名称后缀增强唯一性 3. Kettle 8.x+ 版本需检查`LogChannelFactory`的配置 > **性能提示**:高频调用时建议重用`JobMeta`但每次创建新`Job`实例,平衡资源开销与隔离性[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值