简介:Kettle(Pentaho Data Integration)8.2.0.0-11 完整发行包,是纯Java编写的开源ETL工具,支持Windows、Linux、Unix跨平台运行,面向数据集成与数据仓库建设场景,适合需要处理异构数据库间数据抽取、清洗、转换和加载的开发者、运维人员及数据分析工程师。包内共1884个文件,主体为1335个jar运行库与插件,覆盖对MySQL、Oracle等主流数据库的驱动支持,配合200个ktr转换文件、111个xml配置及cfg、properties、脚本等资源,构成完整转换作业与调度体系;压缩包整体约979.51MB,解压后可直接获得可运行的PDI环境。已有463人下载学习,适合从零搭建Kettle环境并理解作业流程设计。包内含图形化设计、批量执行、定时调度、服务模式等对应的启动脚本;大量示例转换与作业可参照学习多表同步、定时任务、集群部署等常见ETL场景。另附readme与示例数据,便于对照文档验证数据抽取流程。
1. Kettle 8.2 这个 ETL 利器,到底值不值得装
如果你的工作里有一堆“今天要把 A 库的数据搬到 B 库”“把 CSV 清洗完再入数据库”这种定时活,手写脚本虽然能跑,但字段一多、异常一多,维护起来真的会想骂人。Kettle(也叫 PDI)就是干这个的:一个纯 Java 的 ETL 工具,图形化拖拽步骤,不用写代码就能完成数据抽取、清洗、转换、加载。这个 pdi-ce-8.2.0.0-11.zip 是社区版 8.2 的完整安装包,带 Spoon 图形界面和 Pan、Kitchen 命令行工具,适合数据工程师、运维、甚至业务分析师用来做日常数据搬运。我拆过不少环境,8.2 这个版本虽然老了点,但胜在稳定、资料多,社区踩坑贴一搜一堆,新手拿来练手非常合适。
2. 安装与启动:JDK 版本和内存参数先定下来
2.1 版本兼容性:8.2 只认 JDK 8,别用新版本硬上
很多新手下载完 Kettle 8.2,双击 Spoon 没反应,或者闪一下就没下文,十有八九是 JDK 版本不对。8.2 这个版本是基于 Java 8 编译的,你用 JDK 11 甚至 17 跑,轻则启动警告,重则直接起不来。我第一次装的时候图省事,装了 JDK 17,结果 Spoon 一直报UnsupportedClassVersionError,折腾半天换回 JDK 8 才正常。
先确认你机器上的 Java 版本:
java -version如果输出不是 1.8 开头,建议直接装一个 JDK 8。装完之后设置环境变量,Linux 下可以写进/etc/profile:
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 export PATH=$JAVA_HOME/bin:$PATHWindows 下就在系统变量里把JAVA_HOME指到你的 JDK 8 安装目录,然后重启命令行。这里有个细节:Kettle 启动脚本会优先读JAVA_HOME,而不是 PATH 里的 java,所以光改 PATH 没用,必须把JAVA_HOME指对。
2.2 解压与目录作用:别放中文路径,先看懂这六个文件夹
zip 解压出来会得到一个>PENTAHO_JAVA_OPTIONS="-Xmx2048m -Xms512m -XX:MaxPermSize=256m"
Windows 下则改Spoon.bat里的PENTAHO_JAVA_OPTIONS,把-Xmx调大。如果你跑的是命令行批处理,还要改kitchen.sh和pan.sh,因为我发现很多人只改了 Spoon,结果图形界面能跑,一上调度就内存崩溃。
参数说明:
-Xmx2048m表示最大堆内存 2GB,按你的机器内存决定,一般别超过物理内存的一半。-Xms512m是初始堆内存,设大一点可以减少启动时反复扩容的性能损耗。-XX:MaxPermSize只在 JDK 7 以下需要,JDK 8 已经移除了,可以不改。
改完之后用sh spoon.sh启动,看到欢迎界面就算成功。
3. 数据库连接:驱动、URL 和连接池的边界
3.1 驱动包放哪:lib 目录有讲究,版本冲突要小心
Kettle 连数据库靠 JDBC 驱动,驱动 jar 必须放在lib目录下,或者放到libext里用-Djava.ext.dirs指定。我一般直接扔lib,简单省事。
如果你要连 MySQL 8.x,默认附带的老驱动可能不支持,需要下载mysql-connector-java-8.x.jar放进去。放完之后必须重启 Spoon,不然连接配置里看不到新驱动。另外要注意,如果lib里同时存在多个版本的驱动,比如 mysql-connector-java-5.1.48.jar 和 8.0.28.jar,容易出现奇怪的连接失败,最好只留一个。
常见数据库驱动选择:
| 数据库 | 驱动类 | jar 包建议 |
|---|---|---|
| MySQL 5.x | com.mysql.jdbc.Driver | mysql-connector-java-5.1.49 |
| MySQL 8.x | com.mysql.cj.jdbc.Driver | mysql-connector-java-8.0.28 |
| PostgreSQL | org.postgresql.Driver | postgresql-42.5.0 |
| Oracle | oracle.jdbc.driver.OracleDriver | ojdbc8 |
| SQL Server | com.microsoft.sqlserver.jdbc.SQLServerDriver | mssql-jdbc-9.4.0 |
注意 MySQL 8.x 的驱动类名是com.mysql.cj.jdbc.Driver,不是老的com.mysql.jdbc.Driver,写错会报Class not found。
3.2 连接配置:URL 里的参数决定你能不能连上
在 Spoon 里新建数据库连接时,类型选MySQL,主机、端口、数据库名填好,最容易被忽略的是 URL 里的参数。我一般会手动改成这样:
jdbc:mysql://192.168.1.10:3306/analysis?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai参数说明:
useSSL=false:本地或内网数据库通常没配置 SSL 证书,不关掉会报 SSL 连接错误。allowPublicKeyRetrieval=true:MySQL 8 使用 caching_sha2_password 认证时需要这个参数,否则报Public Key Retrieval is not allowed。serverTimezone:必须指定时区,否则连接报时间类型错误。
在 Spoon 的“数据库连接”设置界面,可以把 URL 写进 JDBC 选项里,也可以直接用“选项”标签页一步步填。我习惯直接粘贴 URL,因为有些参数在图形界面里藏得深,容易漏。
3.3 连接池与元数据:这些坑是界面看不出来的
Kettle 默认每个数据库连接会建一个连接池,连接池大小在连接配置的“连接池”标签页里。默认最大连接数是 20,对于并发不高的场景够用。但如果你在转换里开了多线程执行(比如用“复制”步骤),每个线程都会各自占用连接,很容易把连接池打满。我遇到过一次 MySQL 报Too many connections,后来把最大连接数调到 50 才解决。
还有一点,Kettle 的数据库连接在“每次执行时打开/关闭”这个选项上有玄学。如果勾选了“使用连接池”,连接不会每次开关;如果不勾,每次执行步骤都会 disconnect,频繁连库会有明显延迟。我一般保持默认开启连接池,只在极少数特殊场景下关掉。
另外,连接配置里的“表类型”映射也值得注意。比如 MySQL 的TIMESTAMP类型映射到 Kettle 的Timestamp,如果目标表是DATETIME,Kettle 写入时可能出现毫秒精度问题。遇到这类问题,直接在“表输出”步骤里指定字段类型,或者改连接的高级属性。
4. 第一个转换:从 CSV 到数据库的完整流程
4.1 CSV 文件输入:编码、分隔符、表头第一行要确认好
现在拿一个常见场景练手:把订单 CSV 导入 MySQL 的一张表。CSV 内容大概是:
order_id,order_time,user_id,amount,status 1001,2024-01-12 10:23:00,2033,99.50,paid 1002,2024-01-12 11:01:00,2045,199.00,pending在 Spoon 里新建一个转换,拖入“CSV 文件输入”步骤。双击配置:
- 文件:选择 CSV 路径
- 分隔符:
,(逗号) - 编码:UTF-8(如果文件是 GBK,就填 GBK,否则中文乱码)
- 标题字段:勾选第一个行含有字段名
- 点击“获取字段”让 Kettle 自动扫描字段类型
这里最坑的是编码。很多 Windows 下生成的 CSV 是 ANSI 编码,Kettle 默认读 UTF-8,结果中文全部变问号。我一般会先看文件的原始编码,再决定用哪种编码打开。
获取字段后,注意检查日期格式。Kettle 默认把order_time识别成字符串,如果后面要直接入数据库的datetime字段,需要手动改字段类型或加一个“日期时间选择”步骤。
4.2 字段选择与数据清洗:几毛钱的操作别省略
CSV 里可能有多余的列,或者状态值大小写不一致。我在“CSV 文件输入”后面接“字段选择”步骤,只保留需要的字段,重命名、改变类型一步到位:
| 字段名 | 改为 | 类型 | 格式 |
|---|---|---|---|
| order_id | order_id | Integer | - |
| order_time | order_time | Date | yyyy-MM-dd HH:mm:ss |
| user_id | user_id | Long | - |
| amount | amount | Number | 0.00 |
| status | status | String | - |
然后拖入“过滤记录”步骤,把status为PAID或paid的统一成paid,可以用“字符串替换”步骤。我一般写一个简单的正则替换,把大写转小写,再让过滤逻辑只认两个值:paid 和 pending。这里别用太多步骤,能合并的尽量在字段选择里做。
“过滤记录”步骤的条件设置是:
- 条件:
status等于字符串paid - 如果真则走 “已支付” 流,假则走 “未支付” 流
我自己一般会把两条流都接到不同的表输出,或者先统一写入临时表再处理,避免一条流阻塞。
4.3 表输出:批量提交是唯一的关键调优点
表输出步骤配置:
- 连接:选你前面配好的 MySQL 连接
- 目标表:orders
- 提交大小:1000(批量插入的条数)
- 是否自动生成 SQL:可以先点击“SQL”按钮预览建表语句
把写好的 SQL 在数据库客户端执行,或者直接用 Kettle 执行。执行成功后,运行转换,观察底部进度条。
这里我想强调一下“提交大小”。默认是 100,对于大量数据,每 100 条提交一次,数据库日志刷屏不说,速度也很慢。我习惯设成 1000 或 2000,如果目标表有触发器或索引,数据量大时可以提高 30% 以上的效率。但注意,过大的提交大小会造成内存占用上升,接外网数据库时还会增加单次事务的时长,一般建议 500~2000 之间。
转换跑完后,去数据库查一下select count(*) from orders,如果和 CSV 行数对不上,再看日志里的跳过行数。一行数据如果不符合字段格式,Kettle 默认会忽略并记录错误行,这个处理逻辑要专门调,别让脏数据悄悄丢了。
4.4 用命令行运行:没有界面的服务器也能跑
图形界面调试完,最终要部署到服务器跑定时任务,这时候就要用 Pan 命令。写好的转换保存为insert_orders.ktr,放到服务器上,执行:
./pan.sh -file /opt/kettle/jobs/insert_orders.ktr -level Detailed参数说明:
-file:转换文件路径-level:日志级别,Detailed 输出每一步的行数,生产上建议用 Basic,避免日志太大。- 如果转换里用了数据库连接名称,确保服务器上的
.kettle配置文件里也有这个连接,否则会报找不到连接。
在 Windows 上对应用Pan.bat。我通常在本地把转换调好,传到 Linux 服务器用同一套 JDK 8 跑,没出过兼容问题。
5. 避坑指南:启动失败、乱码和资源泄漏的排查
5.1 闪退或者启动后黑屏
现象:双击Spoon.bat或执行sh spoon.sh后,窗口一闪而过,或者停在日志里没有任何图形界面出现。
原因:八成是JAVA_HOME没指向 JDK 8,或者是-Xmx设得太小导致堆空间不足。另外,Linux 环境下没有 DISPLAY 变量也会启动不了图形界面,但你如果是远程 SSH 又没开 X11 转发,就只能用命令行模式。
解决:先执行java -version确认版本;再检查JAVA_HOME环境变量;最后打开spoon.sh的PENTAHO_JAVA_OPTIONS把-Xmx调到 1024m 以上。如果是在纯命令行服务器上跑,别用 Spoon,改用 Pan 和 Kitchen。
5.2 中文乱码,CSV 和数据库双方都乱
现象:CSV 里的中文导入 MySQL 后变成????,或者 Spoon 界面里直接显示乱码。
原因:CSV 文件本身的编码和 Kettle 读取编码不一致;同时数据库连接的 URL 里没有characterEncoding=UTF-8。最常见的是 Windows 下 Excel 导出的 CSV 默认 GBK,Kettle 却按 UTF-8 读。
解决:在“CSV 文件输入”步骤的“编码”一栏手动改成 GBK 或 GB18030。同时把数据库连接的 URL 加上useUnicode=true&characterEncoding=UTF-8。改完重启 Spoon,再重新运行。
5.3 连接 MySQL 时报 Public Key Retrieval is not allowed
现象:测试连接时直接报错,提示Public Key Retrieval is not allowed。
原因:MySQL 8 默认使用caching_sha2_password认证,客户端第一次连接需要获取服务端的公钥,但 JDBC 默认不自动获取。
解决:在连接 URL 加参数allowPublicKeyRetrieval=true&useSSL=false。这个参数在 MySQL 8 的驱动下必须显式打开,否则无论如何连不上。
5.4 数据量一大就 OOM,或者跑一半卡死
现象:CSV 有几千万行,跑到一半报java.lang.OutOfMemoryError: Java heap space。
原因:除了堆内存不够,还可能是表输出“提交大小”太大,或者步骤开启了缓存。Kettle 的“多行流”步骤会缓存大量数据,比如“排序”步骤会把全部数据装进内存。
解决:分三个方向排查。第一,调大-Xmx,建议 4GB 以上;第二,把“排序”换成数据库排序(在排序步骤里选择“数据库排序”),把数据交给数据库处理;第三,检查是否有“JavaScript 代码”步骤存了大的 array,这类步骤会霸占内存。
5.5 作业执行完,数据库连接不释放,导致连接池满
现象:连续跑多个作业后,MySQL 的连接数一直上涨,最后Too many connections。
原因:作业里的转换异常退出时,Kettle 的数据库连接池没有正确关闭,尤其是用了自定义的连接池参数后容易这样。
解决:在作业的“最后”分支里加一个“关闭数据库连接”步骤,或者让作业挂一个“JNDI 连接”由容器统一管理。更保险的做法是在lib里换用较新的数据库驱动,老驱动对连接回收不干净。我后来的习惯是:每个作业都显式在结束前执行一个空洞的数据库查询来触发连接释放,效果还不错。
6. 进阶用法:日志拆分、增量同步和定时调度
当你把基本转换跑通后,下一步自然是让它自己动起来。先说日志:默认日志会输出到$KETTLE_HOME/logs目录,但一个转换跑一天,日志文件能撑到几百 MB。我一般会在 Spoon 里把日志级别从Detailed改成Basic,然后设置“日志表”,把每一步的日志写入数据库中的kettle_log表。这样排查慢步骤时直接查表,不用翻文件。
增量同步是另一个高频需求。用时间戳字段做增量,需要注意两个坑:一是源表的update_time必须建索引,否则全表扫描很痛苦;二是每次同步前要保存“上次同步最大值”。我习惯用变量实现:先在.kettle目录下的配置文件里定义LAST_LOAD_TIME,表输入步骤写:
SELECT * FROM source_order WHERE update_time > CAST('${LAST_LOAD_TIME}' AS TIMESTAMP)跑完转换后,用另一个步骤更新LAST_LOAD_TIME为当前时间。如果你不想手工维护变量,也可以把这些逻辑写进作业,用“设置变量”步骤从数据库读取。
定时调度用 Kitchen 命令加 cron 是最常见的。在 Linux 服务器上,新建一个run_etl.sh:
#!/bin/bash export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 /opt/kettle/data-integration/kitchen.sh -file /opt/kettle/jobs/load_order.kjb -level Basic然后用 crontab 挂上,每天凌晨 2 点跑:
0 2 * * * /opt/kettle/run_etl.sh >> /opt/kettle/logs/cron.log 2>&1跑完一定要检查退出码。Kitchen 执行成功后退出码是 0,非 0 时说明有错误步骤。我在脚本里加了一句:
if [ $? -ne 0 ]; then echo "ETL failed at $(date)" >> /opt/kettle/logs/failed.log exit 1 fi自从加了这行,我再也不怕睡觉时任务悄悄失败。从那以后,我每次部署新的调度任务,都强制走一遍“本机手册跑通 → 命令行低日志跑通 → cron 定时跑通”三关,确认退出码和日志表都生效才算交付。这个习惯帮我省了不知道多少半夜起来的概率,希望帮到你。
本文还有配套的精品资源,点击获取