2026/10/19 16:25:34

Kettle入门实战:从零完成CSV到数据库的ETL转换

Kettle入门实战:从零完成CSV到数据库的ETL转换 Kettle这个词在搞数据的圈子里几乎就是ETL的代名词。哪怕这两年各种云上数据集成服务、大数据平台把数据同步包装得再花哨很多公司内部跑得最稳的报表、数仓、接口对接底子还是Kettle——也就是PDIPentaho Data Integration。说白了你手里有一堆Excel、CSV、各类数据库表每天要做合并、清洗、格式转换、导入导出Kettle就是那个能让你少写几百行代码的图形化工具。这个系列我计划从零开始写今天这篇是第一篇重点解决三件事Kettle到底解决了什么问题、怎么把它装好跑起来、以及如何用拖拽的方式做出第一个把CSV导入数据库的转换。适合刚接触数据的业务分析师、运维同学以及想从脚本里解放出来的开发者。1. Kettle到底是什么为什么到现在还有大量公司在用1.1 ETL这件事过去是怎么干的ETL是Extract、Transform、Load的缩写翻译成人话就是从数据源取数、按业务规则做清洗和转换、最后写入目标存储。在Kettle这类工具普及之前做这件事的主流方式无非三种写Python脚本、写SQL存储过程、写Java定时任务。写脚本灵活度高但问题在于脚本散落在各个服务器上谁也说不清哪个脚本负责哪条链路Python环境升级了某个脚本可能就挂了字段格式变了脚本直接抛异常没人第一时间知道。SQL存储过程的管理相对集中但跨数据库迁移时语法差异让人头疼而且逻辑稍微复杂一点嵌套的SQL能写到一千行后期维护的人心里只剩问候。Java定时任务稳定、可控但对维护者的开发能力要求高一个报表需求下来可能得写一整天代码。我当时第一次接触Kettle是在某公司的数据组做报表对接。对方丢过来一个zip包说用这个工具今天下班前把那个订单表的导入跑起来。从没见过Kettle的我也没多想解压、点开Spoon界面、拖了几个组件、跑了二十分钟目标表里就已经有数据了。那个下午我印象很深原来ETL这件事不一定非要写代码。1.2 Kettle解决的核心痛点Kettle把ETL抽象成一堆可以在画布上拖拽的步骤Step每个步骤负责单一功能读文件、查数据库、做字段计算、去重、排序、写表等等。步骤之间用跳Hop连接起来构成一条数据流。它真正解决了几个核心痛点上手门槛低不需要懂编译不需要会设计模式拖拽组件、填配置就能跑通一条数据链路。跨库能力好同一个转换里可以同时连接MySQL、Oracle、SQL Server、PostgreSQL甚至文本文件、Excel、接口返回的JSON数据在不同来源之间流转非常自然。可视化排错每一步都可以单独预览数据哪一步出了问题一眼就能看到不像脚本那样只能靠日志猜。部署维护简单写好一个转换或作业既可以放在本机跑也能导成脚本交给调度平台定时执行运维成本很低。1.3 PDI和Kettle的名字为什么总混着叫很多新手会困惑有人说Kettle有人说PDI还有人叫Pentaho到底是不是同一个东西说句实在的它们指的是同一个工具的不同时期叫法。早期这个开源项目叫Kettle后来被商业化公司收购产品改名成了PDIPentaho Data Integration但社区版和很多老资料仍然沿用Kettle这个名字。你在网上搜Kettle教程PDI教程内容基本可以互相参考不用太纠结。下载的时候官方现在一般叫Pentaho Data Integration社区里习惯叫Kettle认准Spoon这个图形界面就没跑。搞清楚这点能帮你少浪费不少找资料的时间。2. 装好、能跑从JDK到Spoon窗口的完整准备过程2.1 版本选择里最常见的翻车点我见过太多人卡在安装这一步原因不是操作问题而是JDK版本和Kettle版本不匹配。Kettle本身是Java写的它依赖特定版本的JDK运行装错了直接启动失败报错信息还特别隐晦。我的建议是用Kettle 8.2或8.3配JDK 8。这个组合最经典网上教程资料最多各种数据库驱动兼容性也最好。用Kettle 9.x配JDK 11。新版界面稍微好看一点但遇到的部分插件可能还是按老版本习惯走的需要自己绕一些坑。用Kettle 10.x配JDK 17。最新版功能完善但对新手不算友好驱动和插件的兼容问题也更多。如果你想快速上手我实际推荐Kettle 8.3配JDK 8踩坑成本最低。先跑通全流程再考虑要不要升级版本这是最务实的路径。2.2 下载、解压与目录结构下载下来的包通常是一个zip解压后会看到一个名为>PENTAHO_DI_JAVA_OPTIONS-Xms1024m -Xmx2048m -XX:MaxPermSize256m如果你机器内存够大可以改成PENTAHO_DI_JAVA_OPTIONS-Xms1024m -Xmx4096m -XX:MaxPermSize512m -Dfile.encodingUTF-8-Xmx决定了JVM能用的最大堆内存处理大文件时特别关键。-Dfile.encodingUTF-8是保证控制台日志和读取文本文件时的默认编码是UTF-8能少很多乱码问题。改完保存重新启动Spoon就生效了。3. Kettle的三个核心概念搞懂它们才能不迷路3.1 转换Transformation流水线模型Kettle里最核心的东西是转换。每个转换里可以放多个步骤步骤之间用Hop连线数据就像流水线上的零件从一个工位流向下一个工位。最重要的特点是转换里的数据是流式和并行处理的每个步骤拿到数据后边处理边向下传不是等全部读进来再统一加工。正因为这样几十万行数据在转换里跑起来也很快因为内存里同一时刻只保留一小部分数据。举个例子一个最简单的转换可以是CSV文件输入 - 字段过滤 - 文本文件输出。CSV输入逐行读过滤步骤逐行判断文本输出逐行写三个步骤几乎同时在干活。转换解决的问题是单条数据怎么变它适合做数据加工但不适合做流程编排。3.2 作业Job做决策的老板如果说转换是流水线那作业就是安排流水线的老板。作业是面向任务流程的先执行一个转换、成功了就给指定邮箱发邮件、失败了就写一条日志再重跑这些都靠作业来编排。作业里的组件叫作业项常见的有转换、SQL脚本、发送邮件、复制文件、检查文件是否存在、Javascript等。作业项之间靠连线决定执行顺序连线上还可以设置成功/失败的条件连接形成条件分支。一个典型作业的流程是检查今天的文件是否到达 - 到了就执行转换导入数据 - 导入成功发邮件通知 - 导入失败触发告警脚本。搞不清转换和作业的区别是新手最开始最容易犯的混淆。一张表帮你分清楚对比维度转换作业核心作用加工单条数据编排多个任务执行特点流式、并行串行、按条件跳转内部组件步骤Step作业项Job Entry代表场景CSV读取、字段清洗、写库定时调度、发送邮件、失败重试连线的含义数据流向执行顺序和条件注意作业本身不处理数据它只负责指挥。真正干活的还是它调用的那些转换。3.3 资源库Repository保存你的工作成果每次新建的转换和作业如果不主动保存关闭Spoon就没了。保存的地方叫资源库有两种最基本的类型文件资源库和数据库资源库。文件资源库就是把所有内容存成本地的XML文件好处是简单、离线可用、不怕数据库挂掉适合单人或小团队。数据库资源库是把所有内容保存在数据库表里适合多人协作谁都能看到同一套最新版本。新手阶段我建议直接用文件资源库路径选一个好找的目录每个转换保存成独立的.ktr文件每个作业保存成.kjb文件。这种文件可以拷贝、可以交给同事、也可以放进版本管理工具里做备份最灵活。数据库资源库虽然协作方便但里面关系表很多出问题后处理起来麻烦等你有经验了再用不迟。3.4 变量与命名参数写死的文件路径和数据库连接串在测试环境和生产环境切换时要一个个改特别容易漏。Kettle支持用${变量名}的方式引用环境变量或自定义参数。Spoon右上角可以设置环境变量转换里也可以定义命名参数。比如文件路径写成D:/data/${report_date}/order.csv运行转换时通过命令行传入report_date20250420就能自动切换到对应日期的文件。这个习惯值得一开始就养成否则后面做定时调度会很痛苦。4. 动手做第一个转换把一个CSV变成数据库表4.1 先说要干什么一个真实的订单导入场景假设你现在遇到一个实际的业务需求某部门每天会导出一个订单明细的CSV文件字段包括订单号、下单时间、订单金额、订单状态大概几万行。你需要把它清洗一遍过滤掉状态为已取消的记录然后导入MySQL数据库的表里供报表系统使用。第一步肯定不是在Kettle里乱拖而是先在纸上理一遍数据流向读取CSV原始数据把金额字段从字符串转成数字过滤掉已取消的订单只保留我们关心的几个字段写入数据库这个思路跟写程序一模一样只是现在用Kettle把它可视化出来。4.2 新建转换和CSV文件输入组件打开Spoon在菜单里选文件 - 新建 - 转换画布就出来了。左侧的核心对象面板里找到输入分类拖一个CSV文件输入到画布上。双击组件开始配置文件路径填CSV的实际路径比如D:/data/order_20250420.csv。分隔符多数CSV是逗号如果你的文件是别的符号就对应改。编码这里选UTF-8关于乱码问题后面有专门的坑要讲。点获取字段按钮Kettle会自动读文件头几行把字段名列出来你只需要确认类型对不对。这里有个非常实用的心得能点获取字段就不要手动敲字段。自动识别又快又准还不会漏掉字段。识别出来以后把所有字段的类型检查一遍金额类字段如果读成了String后面可以靠另一个步骤改也可以在这直接改。配置完后先点预览按钮能直接看到这个步骤产生的前100行数据。预览是Kettle最值钱的功能之一每步都能预览意味着你可以在每个环节确认数据长什么样而不是最后跑完才发现问题。4.3 数据清洗字段选择、过滤、值映射CSV读进来以后先做字段整理。从转换分类里拖一个字段选择组件连到CSV输入后面。双击后可以把不要的字段从右侧删除列表里移除也可以在元数据标签里修改字段名称和类型。金额字段如果没有被正确识别成数值在这里把它改成BigDecimal或Number类型更稳妥。接下来是过滤规则。拖一个过滤记录组件连在字段选择后面双击配置条件比如筛选订单状态不等于已取消的记录。条件表达式可以点编辑按钮生成不用手写语法选择字段、选择运算符、填上比较值就行。如果你还需要做更灵活的映射比如把待发货已发货统一成处理中可以用值映射组件。这些都是非常基础的转换组件组合起来已经能解决大部分清洗需求。4.4 数据库连接和表输出清洗完数据要写进MySQL。先把MySQL的JDBC驱动jar包mysql-connector-java-xxx.jar拷贝到Kettle的lib目录下然后重启Spoon。这一步经常有人忘驱动没放进去后面配置数据库连接时怎么都测试不通过。完成驱动部署后在左侧输出分类里拖一个表输出组件连线接在过滤记录后面。双击配置连接按钮右边点新建选择MySQL类型填入主机名、端口默认3306、数据库名、用户名、密码。点测试按钮提示连接成功后保存。目标表里填你要写入的表名比如ods_order。如果表还不存在可以切换到SQL标签页让Kettle根据你流里的字段生成建表语句确认后执行。表输出组件还有个关键参数是批量插入大小默认值可能较小。如果数据量很大可以适当调大比如设置成1000或2000写入速度会有肉眼可见的提升。事务方面建议勾选忽略错误的选项时谨慎一点生产环境宁可报错也不要静默丢数据。4.5 运行、预览与排错配置完成后点击画布上方的运行按钮选择本地执行Kettle就开始跑。跑的过程中每个步骤旁边会有行数统计读了多少行、过滤掉多少行、写了多少行一目了然。如果中间某个步骤报错日志面板里会显示具体是哪一步、什么样的异常。最常见的是类型转换错误比如某一行数据里金额字段出现了一个空字符串或者特殊符号转数字时失败。解决办法看你业务场景可以用数据校验组件提前把异常数据分流也可以用过滤记录先把脏数据拦掉总之不要让异常数据直接打到报错那一层。跑完之后去数据库里SELECT COUNT(*)验证一下行数再随机抽几行看字段值是否正确这就算完成了一个完整的Kettle转换。5. 新手最容易踩的几个坑我替你踩过了5.1 中文乱码到底是谁的锅乱码是新手报错率最高的问题而且一旦乱码数据基本就不能用了。关键是乱码可能发生在三个环节任何一个不对最终结果就是一堆问号。CSV文件本身的编码很多Windows环境下导出的CSV是GBK编码不是UTF-8。用记事本另存为或先看一眼文件编码明确真正的编码。Kettle读取组件里的编码选项必须跟文件实际编码一致。文件是GBK组件里却选UTF-8读进来就是乱码反过来的情况也一样。数据库连接编码MySQL连接串上要加characterEncodingutf8同时表和库的字符集也要是utf8mb4或utf8。排查乱码的思路很简单先预览CSV输入步骤的输出如果这一步已经乱了说明是文件编码和读取编码不一致如果这一步正常写进数据库才乱那问题在数据库连接和表字符集上。用排除法定位不要瞎蒙。5.2 装了驱动还是报找不到驱动数据库连接测试失败找不到驱动类是高频报错。很多人明明把jar包放进lib目录了依然报错那多半是这几个原因jar包放错位置或没有重启Spoon。Kettle启动时加载lib目录下的jar放完文件必须重启才生效。驱动版本和数据库版本不匹配。老MySQL配新驱动、新MySQL配太老的驱动都有问题。一般建议MySQL用mysql-connector-java-5.1.x系列兼容性最好8.x数据库可以配8.0.x驱动。连接类型选错。选MySQL时驱动类名一般是com.mysql.jdbc.Driver或com.mysql.cj.jdbc.DriverKettle自动填充理论上不需要手动改但如果你从网上复制了别的连接串覆盖了默认值就可能填错。驱动问题排查时先看日志里提示缺哪个类然后去lib目录搜一下那个类在不在这在大多数情况下能直接定位。5.3 内存不足的崩溃体验处理几十万行数据时Spoon可能直接报OutOfMemoryError或者闪退。很多人第一反应是Kettle不行其实大多数是启动内存配置太小的锅。前面第2.4节里改的-Xmx参数就是应对这个问题的。如果你处理的是上百万行级别建议把-Xmx给到4G或更大。但内存粉饰不了一切的过度设计转换里也别把所有数据都攒在一个步骤里不往下流尽量保持流式处理。另一个思路是不要一次全量抽取用增量抽取每次只处理新增或变更的数据比如按日期字段过滤或者记录上次处理的ID和位置。Kettle里做增量抽取的方式很多命名参数、变量、SQL里写WHERE update_time ${last_time}都是常用做法。先把全量做通再考虑增量优化这是最稳的上手路线。5.4 运行结果和预期不一致还有一种比较隐蔽的问题转换跑成功了但结果跟你预期不一样。比如行数少了一些、某个字段全是空值、或者某些数字对不上。我遇到过几种典型情况预览和实际运行结果不一致预览只取前100行汇总字段比如分组统计在预览时算出来的可能只是部分数据的结果不要拿预览当全量结果。类型转换静默失败字符串转数字时遇到非数字内容Kettle会按它的非严格模式处理可能把这一行置空而不报错。你看到某列大量空值但日志没有异常时先怀疑这里。过滤条件写反了过滤记录组件里发送true到第一个步骤false到第二个新手容易把条件方向搞反导致想要的数据走了错的分支。跑完后对账是好习惯源表总行数、过滤后行数、目标表行数三者要能对上逻辑。对不上就按步骤逐个预览排查很快能锁定是哪一步出了问题。6. 写在第一篇的末尾我的一点使用心得6.1 一套稳定的学习路径回首我自己刚学Kettle那会儿最实用的路径其实是先跑通一个完整的转换CSV到数据库就够再把转换和作业的关系搞清楚最后学会用变量和参数。掌握这三样你已经能解决日常七八成的ETL需求。至于集群、资源库、复杂性能调优都是遇到真实场景后再针对性补课的事一上来就啃难点反而容易劝退。6.2 从维护成本角度看Kettle的价值很多团队宁可让开发写Python脚本也不愿意用Kettle理由往往是代码能进版本库、看得懂。这个理由有一定道理但脚本散落之后的管理问题同样会反噬。我在实际项目里体会最深的是图形化链路讲解起来太方便了——把画布打开谁是上游、谁是下游、哪里过滤、哪里写入一清二楚。交接给新同事的成本比贴一堆代码低得多。下一篇我准备写Kettle作业的调度和自动化怎么定时跑、怎么传变量、怎么失败重试和邮件告警。这些是让Kettle从手工工具变成生产链路的关键一步。如果你正在被重复的数据处理折磨先把今天这篇的转换跑通下一篇文章你就能把它挂上定时任务了。