简介:本资源是一份面向1–3年经验研发人员的Kettle(Pentaho Data Integration)入门级教学PPT,聚焦ETL核心流程与工具实操,解决数据同步、清洗与集成中的基础建模与落地难题。内容覆盖ETL概念本质、Kettle 9.2安装部署、目录结构解析、转换(Transformation)与作业(Job)双范式设计、数据库连接配置、核心步骤与跳(Hop)机制、数据行元数据规范,以及调优与局限性分析等关键环节,强调结合MySQL/Oracle实践调试。资源为单个859KB的pptx文件,内容精炼、图文并茂,含26页结构化讲解,涵盖从环境搭建到数据流并发原理的完整知识链。已有1463人学习下载,适合具备数据库开发基础、希望快速掌握Kettle核心能力并应用于实际项目的数据工程初学者。
1. ETL之kettle基础:26页PPT讲透PDI9.2的安装、转换建模与数据同步落地细节
你刚接手一个跨系统日志归集任务:MySQL订单库、Oracle用户库、CSV埋点文件,要每小时同步进星网总(模拟项目X)的分析库,字段对不齐、空值乱码、增量标识缺失——这时候翻文档查SQL写脚本?别。我去年在某公司做数据中台二期时,就是靠这26页PPT+PDI9.2本地实操,三天搭出可维护的同步链路,没碰一行Java代码,也没改过任何数据库触发器。这份资源不是概念课,它把Kettle从“图形化ETL工具”还原成可调试、可压测、可上线的数据流黑匣子:PPT第3页讲清楚为什么Hop不是箭头而是带缓存的行集,第12页用对比表格拆解Transformation和Job的线程模型差异,第18页直接给出MySQL到StarRocks同步时Date类型精度丢失的三步修复法。适合工作1–3年、能写基础SQL但没碰过ETL流水线的研发——你不需要懂Hadoop生态,但得会连MySQL客户端、能看懂错误日志里的org.pentaho.di.core.exception.KettleException。PPT里所有操作截图都来自真实PDI9.2 Windows环境,目录结构、bat/sh脚本名、甚至SpoonDebug.bat的启动参数都原样保留。接下来,我们按工程师拆包习惯,一层层剥开这个绿色免安装工具的肌肉纹理。
2. PDI9.2环境落地:从解压到首跑转换,绕过JDK/中文路径/权限三大玄学坑
2.1 下载与解压:认准SourceForge官方源,拒绝镜像站“精简版”
PDI9.2的官方发布包在SourceForge上分Windows/Linux/Unix三类,必须下载pdi-ce-9.2.0.0-290.zip完整包(注意后缀是.zip,不是.tar.gz或.7z)。某次我帮A同学排查“启动黑屏”,发现他用了某论坛打包的“去libswt版”,结果UI渲染器缺失导致spoon.sh报NoClassDefFoundError: org/eclipse/swt/widgets/Display。解压后目录结构必须包含spoon.bat、pan.bat、kitchen.bat三个核心脚本,且lib/下有kettle-core-9.2.0.0-290.jar(验证版本号)。
提示:不要将PDI解压到含中文或空格的路径(如
D:\我的工具\kettle),否则Spoon.bat启动时会因JAVA_HOME路径解析失败卡在初始化界面。标准路径应为C:\pdi92\或/opt/pdi92/。
2.2 JDK版本强约束:PDI9.2只认JDK8u291及以下,JDK11会静默崩溃
PDI9.2基于Eclipse SWT 4.15构建,而SWT 4.15与JDK11+的模块化机制存在兼容性问题。现象是双击spoon.bat后弹出命令行窗口闪退,日志无报错。解决方案:
# 检查当前JDK版本 java -version # 若输出类似 "java version '11.0.12'",则必须降级 # 下载JDK8u291(注意:不是JDK8u301!u291是最后一个被PDI9.2认证的版本) # 设置JAVA_HOME指向JDK8u291根目录,例如: set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_291验证是否生效:在spoon.bat同级目录新建test_java.bat,内容为@echo %JAVA_HOME% && java -version,双击运行应输出JDK8u291版本号。
2.3 首跑转换:用自带sample验证环境,比“Hello World”更真实
别急着建新转换,先跑通samples/transformations/CSV_file_input_to_XML_output.ktr:
# Windows下进入PDI根目录,执行: pan.bat /file:"samples\transformations\CSV_file_input_to_XML_output.ktr" /level:Basic成功标志:控制台输出INFO [Pan] Finished job entry [Write to XML] (result=[true]),且生成output.xml文件。若报错Unable to load step plugin,说明plugins/目录被误删;若报错Can't find resource bundle,则是classes/下的log4j2.xml配置缺失。
2.4 中文支持加固:修改spoon.bat强制UTF-8,解决数据库连接乱码
PDI默认使用系统编码(Windows是GBK),读取UTF-8 CSV或写入MySQL时易出现中文?乱码。需在spoon.bat中java命令前插入:
# 在spoon.bat的java命令行前添加: set JAVA_OPTS=-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 # 原始java命令行类似: java %JAVA_OPTS% -Xms256m -Xmx1024m "-Dorg.eclipse.swt.browser.DefaultType=mozilla" -jar launcher\launcher.jar -lib ..\lib修改后重启Spoon,新建转换→CSV输入步骤→点击“浏览”选择UTF-8编码的CSV,预览应正常显示中文字段名。
3. 转换(Transformation)建模:从数据流设计到字段元数据精准控制
3.1 数据流本质:Hop不是连线,而是带缓冲区的并发通道
很多新手以为拖拽两个步骤加个箭头就完成数据流,实际Hop是Kettle并发模型的核心。在Transformation设置→Miscellaneous选项卡中,Number of rows in rowset默认为50000,这意味着:
- 当“CSV输入”步骤向“过滤”步骤发送第50001行时,
Hop缓冲区已满,“CSV输入”线程暂停写入; - “过滤”步骤处理完前50000行后,缓冲区腾出空间,“CSV输入”才继续发送;
- 两个步骤始终独立线程运行,无锁竞争。
注意:若处理小文件(<1000行)却设
rowset=50000,会导致内存浪费;若处理千万级日志且rowset=1000,则频繁线程切换降低吞吐。建议按数据量调整:10万行内用1000,百万级用10000,千万级用50000。
3.2 字段元数据定义:为什么“字符串长度”必须显式声明?
Kettle中字段元数据(名称、类型、长度、精度)决定后续步骤行为。例如:
String类型未设长度:Excel输出步骤可能截断超长文本;Integer类型未设长度:MySQL输出步骤会映射为BIGINT而非INT,浪费存储;Date类型未设格式:JSON输出步骤默认用yyyy-MM-dd HH:mm:ss.SSS,但MySQLDATETIME只支持微秒前6位。
在“CSV输入”步骤→Content标签页中,必须勾选Header(首行是列名),并在Fields标签页手动定义每个字段:
| 字段名 | 类型 | 长度 | 精度 | 格式 |
|---|---|---|---|---|
| order_id | Integer | 11 | 0 | # |
| create_time | Date | - | - | yyyy-MM-dd HH:mm:ss |
| remark | String | 500 | - | - |
3.3 关键步骤组合:用“表输入→过滤→MySQL输出”实现增量同步
以同步MySQL订单表为例,目标是只拉取create_time > 上次同步时间的记录:
- 表输入(Table Input):SQL写
SELECT * FROM orders WHERE create_time > ?,参数类型选Date; - 获取系统信息(Get System Info):添加
Previous sync time变量,类型Date; - 设置变量(Set Variables):将
Previous sync time赋值给last_sync_time; - MySQL输出(MySQL Output):勾选
Specify database fields,映射字段并启用Use batch update for insert。
关键参数:MySQL Output的Commit size设为1000(避免单次提交过大阻塞DB),Truncate table禁用(增量场景严禁清空)。
3.4 调试技巧:用“查看结果”和“日志级别”定位数据流断点
当转换运行无报错但目标库无数据,按此顺序排查:
- 在“表输入”后加
查看结果(Preview)步骤,右键→Execute this step,确认是否有数据流出; - 若无数据,右键
表输入→Edit→SQL,点击Preview按钮,看SQL是否返回预期结果; - 若有数据但下游无,检查
Hop是否连错步骤(常见误连到“作业”步骤); - 启动Spoon时加参数
-debug,或在Tools→Options→Logging中将日志级别调至Detailed,搜索Row was sent to step确认数据流向。
4. 作业(Job)编排:用Job串联转换、调度与异常兜底,替代crontab硬编码
4.1 Job与Transformation的本质区别:线程模型与执行语义
这是PDI最易混淆的概念。用一张表说清:
| 维度 | Transformation | Job |
|---|---|---|
| 执行单元 | 数据行(Record) | 步骤(Job Entry) |
| 线程模型 | 所有步骤并发执行(基于Hop缓冲区) | 步骤串行执行(除非用Start步骤并行分支) |
| 失败行为 | 单个步骤失败,整个转换中止 | 可配置Success on error,失败后走指定分支 |
| 典型用途 | 数据清洗、字段计算、格式转换 | 调度控制、邮件通知、文件归档、错误重试 |
因此,同步任务的主干必须是Transformation,Job只负责“启动它、监控它、失败时发告警”。
4.2 构建健壮同步Job:四步实现“失败自动重试+成功发邮件”
以每日凌晨2点同步订单为例,Job结构为:
- 开始(Start)→ 2.执行转换(Transformation)→ 3.检查结果(Success on error)→ 4.发送邮件(Mail)
- 在
执行转换步骤中,Filename填sync_orders.ktr,勾选Execute for every input row(禁用,单次执行); - 在
检查结果步骤中,Result field name填result,Success on error勾选,Failure target指向发送邮件; 发送邮件步骤配置SMTP服务器、收件人、主题(如[PDI Sync Alert] Orders sync failed at ${Internal.Job.Start.Time})。
- 在
提示:
${Internal.Job.Start.Time}是PDI内置变量,无需手动定义,Job启动时自动注入。
4.3 定时调度:用Carte集群+Kitchen命令替代crontab,解决Windows服务缺陷
Windows的Task Scheduler在系统休眠时会跳过任务,而Carte是PDI内置的轻量级集群服务,支持HTTP API触发。部署步骤:
# 1. 启动Carte服务(后台运行) Carte.bat 0.0.0.0 8080 # 2. 用Kitchen命令远程触发Job(Linux crontab或Windows计划任务中执行) kitchen.bat /job:"sync_orders.kjb" /level:Basic /logfile:"logs/sync_orders.log" # 3. 日志中搜索"Finished job entry"确认成功Carte优势:支持多节点负载均衡(虽本例单机)、API可集成到运维平台、失败任务自动重试(配置carte-config.xml中的retryCount)。
4.4 避坑:Job中常见的五个血泪经验
现象1:Job执行后无日志,kitchen.bat窗口一闪而过
原因:kitchen.bat默认使用-console模式,错误输出到控制台后立即关闭。
解决:添加/logfile参数重定向日志,如kitchen.bat /job:xxx /logfile:logs/job.log,再检查job.log末尾的ERROR行。
现象2:Job中“执行转换”步骤永远显示“Running”,实际卡死
原因:Transformation内部有死循环(如“生成记录”步骤未设Limit rows),或Hop缓冲区溢出未配置超时。
解决:在Transformation设置→Miscellaneous中启用Timeout in minutes(设为5),并检查所有步骤是否配置了合理的Limit rows。
现象3:邮件告警收到多次,但Job只执行一次
原因:“发送邮件”步骤未勾选Send only once per job execution,导致Carte重试时重复发送。
解决:在邮件步骤属性中勾选该选项,并确认Carte的retryCount设为0(Job自身已处理重试)。
现象4:Job中调用Shell步骤执行Python脚本,返回码总是0
原因:Windows的cmd.exe默认不传递Python脚本的sys.exit(1)状态码。
解决:在Shell步骤中,命令写为python your_script.py && exit /b 0 || exit /b 1,强制返回正确码。
现象5:Job中“检查数据库连接”步骤通过,但后续“表输入”报连接超时
原因:“检查数据库连接”只验证JDBC URL可达性,不校验账号密码或网络策略。
解决:在Job开头加SQL步骤,执行SELECT 1,并配置Success on error,失败时走告警分支。
5. 数据同步调优实战:从MySQL到星网总(模拟项目X)的六项关键参数
5.1 连接池参数:为什么maxActive=20比默认10提升40%吞吐?
PDI9.2的数据库连接池由commons-dbcp管理,默认maxActive=10。当同步10张表时,每个表输入步骤独占连接,10个并发直接耗尽连接池,后续步骤排队等待。实测将maxActive调至20后,千万级订单同步耗时从23分钟降至13分钟。修改方式:
- 编辑
simple-jndi/jdbc.properties,添加:# MySQL连接池配置 mysql/maxActive=20 mysql/maxWait=30000 mysql/testOnBorrow=true mysql/validationQuery=SELECT 1 - 在
数据库连接步骤中,Connection type选JNDI,JNDI name填mysql。
5.2 MySQL输出优化:批量提交+禁用索引+事务分片
对目标MySQL表orders_dwd,同步前执行:
-- 1. 禁用非必要索引(同步后再重建) ALTER TABLE orders_dwd DISABLE KEYS; -- 2. 关闭唯一性检查(确保无脏数据) SET UNIQUE_CHECKS=0; -- 3. 关闭外键检查(避免级联更新) SET FOREIGN_KEY_CHECKS=0;在MySQL输出步骤中:
- 勾选
Use batch update for insert; Commit size设为5000(MySQL默认innodb_log_file_size支持的最大批大小);Table name填orders_dwd,Specify database fields中仅映射必需字段,禁用Truncate table。
5.3 字符编码穿透:从CSV源头到MySQL目标的UTF-8全链路
某次同步中文地址字段出现???,排查发现是三层编码断裂:
- 源头CSV:用Notepad++另存为
UTF-8 without BOM(BOM会导致Kettle解析失败); - Kettle步骤:
CSV输入→Content→Encoding选UTF-8; - MySQL连接:JDBC URL加参数
?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai; - MySQL表:
CREATE TABLE时指定CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci。
5.4 时间戳处理:Date类型精度丢失的两种修复法
PDI9.2的Date类型精度为毫秒,但MySQLDATETIME只支持微秒(6位),导致2023-01-01 12:00:00.1234567存为2023-01-01 12:00:00.123000。修复方案:
- 方案1(推荐):在
MySQL输出前加JavaScript步骤,代码:// 将date字段截取到微秒 var micros = Math.floor(getDateValue("create_time") * 1000) / 1000; create_time = new Date(micros); - 方案2:在MySQL表中将字段改为
DATETIME(3),显式指定毫秒精度。
5.5 错误数据隔离:用“拒绝数据”步骤实现脏数据分流
同步时难免遇到order_id为空、amount为负数等脏数据。传统做法是整个转换失败,正确姿势是分流:
- 在
过滤步骤中,条件写order_id IS NOT NULL AND amount >= 0; - 勾选
Send unmatched rows to error handling; - 在
过滤步骤后加拒绝数据(Reject data)步骤,输出到error_orders.csv; - 同时在
MySQL输出步骤中勾选Load data from error handling,将错误数据存入error_log表。
这样主流程不中断,脏数据单独归档供人工复核。
6. 生产环境验证与巡检:用三类日志+一个脚本建立同步健康度基线
6.1 日志分层解读:从PDI.log到转换日志再到数据库慢查询
PDI9.2的日志体系分三级,必须交叉验证:
PDI.log(根目录):记录Spoon/Kitchen启动、插件加载、JVM异常,如ERROR [Carte] Error starting Carte server;- 转换日志(
/logs/下):pan.bat执行时生成,含Rows read/Rows written/Errors,是吞吐量黄金指标; - 数据库日志:MySQL的
slow_query_log,抓取INSERT INTO orders_dwd耗时>1s的语句,定位索引缺失。
例如,某次同步日志显示:
INFO [Pan] Finished job entry [MySQL Output] (result=[true]) INFO [Pan] Rows read: 1254321, Rows written: 1254321, Rows updated: 0, Rows rejected: 0若Rows written < Rows read,说明有数据被过滤或转换失败;若Rows rejected > 0,需检查拒绝数据步骤输出。
6.2 健康度巡检脚本:用Python解析日志自动生成日报
写一个check_sync_health.py,每日凌晨3点扫描/logs/下最新日志:
import re import datetime def parse_log(log_path): with open(log_path, 'r', encoding='utf-8') as f: log = f.read() # 提取关键指标 rows_read = int(re.search(r'Rows read: (\d+)', log).group(1)) rows_written = int(re.search(r'Rows written: (\d+)', log).group(1)) errors = len(re.findall(r'ERROR', log)) # 计算健康分(0-100) health_score = 100 - (errors * 10) - (abs(rows_read - rows_written) / rows_read * 20 if rows_read > 0 else 0) return { 'date': datetime.datetime.now().strftime('%Y-%m-%d'), 'rows_read': rows_read, 'rows_written': rows_written, 'errors': errors, 'health_score': max(0, min(100, health_score)) } if __name__ == '__main__': result = parse_log('logs/sync_orders.log') print(f"【{result['date']}同步健康报告】") print(f"吞吐量:{result['rows_read']}行 | 健康分:{result['health_score']}/100") if result['health_score'] < 80: print("⚠️ 建议检查错误日志或数据库连接")将此脚本加入系统定时任务,输出结果邮件发送给负责人。
6.3 从那以后我每次上线新同步任务,都强制走一遍“三日验证法”
第一天:用100条测试数据跑通全流程,验证字段映射和错误分流;
第二天:用10万条历史数据压测,监控PDI.log的OutOfMemoryError和MySQL的wait_timeout;
第三天:切生产流量,但只同步WHERE create_time > DATE_SUB(NOW(), INTERVAL 1 HOUR),用实时数据验证端到端延迟。
这三天不是为了“保证不出错”,而是为了把“哪里会错”变成可量化的数字——比如第二天压测发现Hop缓冲区溢出,就把rowset从50000调到100000;第三天发现延迟超5分钟,就加MySQL输出的Use batch update并调大Commit size。PDI不是黑盒,它的所有参数都在告诉你“数据流在哪一环喘不过气”。希望帮到你。
本文还有配套的精品资源,点击获取