资讯详情

资讯详情

Kettle 8.2 ETL工具实战:安装配置、数据库连接与数据同步

简介KettlePentaho Data Integration8.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/profileexport 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:MaxPermSize256mWindows 下则改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.xcom.mysql.jdbc.Drivermysql-connector-java-5.1.49MySQL 8.xcom.mysql.cj.jdbc.Drivermysql-connector-java-8.0.28PostgreSQLorg.postgresql.Driverpostgresql-42.5.0Oracleoracle.jdbc.driver.OracleDriverojdbc8SQL Servercom.microsoft.sqlserver.jdbc.SQLServerDrivermssql-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?useUnicodetruecharacterEncodingUTF-8useSSLfalseallowPublicKeyRetrievaltrueserverTimezoneAsia/Shanghai参数说明useSSLfalse本地或内网数据库通常没配置 SSL 证书不关掉会报 SSL 连接错误。allowPublicKeyRetrievaltrueMySQL 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如果目标表是DATETIMEKettle 写入时可能出现毫秒精度问题。遇到这类问题直接在“表输出”步骤里指定字段类型或者改连接的高级属性。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_idorder_idInteger-order_timeorder_timeDateyyyy-MM-dd HH:mm:ssuser_iduser_idLong-amountamountNumber0.00statusstatusString-然后拖入“过滤记录”步骤把status为PAID或paid的统一成paid可以用“字符串替换”步骤。我一般写一个简单的正则替换把大写转小写再让过滤逻辑只认两个值paid 和 pending。这里别用太多步骤能合并的尽量在字段选择里做。“过滤记录”步骤的条件设置是条件status等于字符串paid如果真则走 “已支付” 流假则走 “未支付” 流我自己一般会把两条流都接到不同的表输出或者先统一写入临时表再处理避免一条流阻塞。4.3 表输出批量提交是唯一的关键调优点表输出步骤配置连接选你前面配好的 MySQL 连接目标表orders提交大小1000批量插入的条数是否自动生成 SQL可以先点击“SQL”按钮预览建表语句把写好的 SQL 在数据库客户端执行或者直接用 Kettle 执行。执行成功后运行转换观察底部进度条。这里我想强调一下“提交大小”。默认是 100对于大量数据每 100 条提交一次数据库日志刷屏不说速度也很慢。我习惯设成 1000 或 2000如果目标表有触发器或索引数据量大时可以提高 30% 以上的效率。但注意过大的提交大小会造成内存占用上升接外网数据库时还会增加单次事务的时长一般建议 5002000 之间。转换跑完后去数据库查一下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 里没有characterEncodingUTF-8。最常见的是 Windows 下 Excel 导出的 CSV 默认 GBKKettle 却按 UTF-8 读。解决在“CSV 文件输入”步骤的“编码”一栏手动改成 GBK 或 GB18030。同时把数据库连接的 URL 加上useUnicodetruecharacterEncodingUTF-8。改完重启 Spoon再重新运行。5.3 连接 MySQL 时报 Public Key Retrieval is not allowed现象测试连接时直接报错提示Public Key Retrieval is not allowed。原因MySQL 8 默认使用caching_sha2_password认证客户端第一次连接需要获取服务端的公钥但 JDBC 默认不自动获取。解决在连接 URL 加参数allowPublicKeyRetrievaltrueuseSSLfalse。这个参数在 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 21跑完一定要检查退出码。Kitchen 执行成功后退出码是 0非 0 时说明有错误步骤。我在脚本里加了一句if [ $? -ne 0 ]; then echo ETL failed at $(date) /opt/kettle/logs/failed.log exit 1 fi自从加了这行我再也不怕睡觉时任务悄悄失败。从那以后我每次部署新的调度任务都强制走一遍“本机手册跑通 → 命令行低日志跑通 → cron 定时跑通”三关确认退出码和日志表都生效才算交付。这个习惯帮我省了不知道多少半夜起来的概率希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →