当前位置:首页 > 问答 > 正文

聊聊Kettle里头怎么同时搞定俩数据库那些事儿和小技巧

这事儿说白了,就是让Kettle这个数据搬运工,能左手从A数据库拿东西,右手放到B数据库里去,中间可能还得做点清洗、转换的小动作,核心在于怎么让这两个“仓库”顺畅地对话。

最基础也最常用的法子:用“表输入”和“表输出”搭档。

这招儿直来直去,最容易上手,你就在转换里拖一个“表输入”步骤,配置好第一个数据库的连接,写上SQL语句,把想要的数据查出来,再拖一个“表输出”或者“插入/更新”步骤,配置好第二个数据库的连接,指定好数据要放进哪张表里,最后用一根线把“表输入”和“表输出”连起来,点一下运行,数据就“唰”地一下过去了。

这里头有几个非常实用的小技巧:

聊聊Kettle里头怎么同时搞定俩数据库那些事儿和小技巧

  1. 连接参数化是个宝:你别傻乎乎地把数据库的IP、用户名、密码直接写死在转换里,万一数据库换了地方,你得一个个改,能累死,一定要用Kettle的“参数”功能,在转换或者作业的“命名参数”那里,定义几个变量,比如SOURCE_DB_IPTARGET_DB_USER啥的,然后在建立数据库连接的时候,主机名那里就填${SOURCE_DB_IP},用户名填${TARGET_DB_USER},这样,以后只要在运行前改一下参数值,或者通过命令行传参,就能灵活应对不同环境,特别方便。(来源:Kettle官方文档关于变量和参数使用的部分)
  2. “插入/更新”比“表输出”更智能:“表输出”是管杀不管埋,它只会一股脑地往里插新数据,如果表里有主键重复,它就报错罢工,而“插入/更新”步骤就聪明多了,你可以设置用来比较的关键字段(比如订单ID),Kettle会先帮你查一下目标表里有没有这个ID,如果没有,就执行插入;如果已经有了,就更新那条旧记录,这在同步数据的时候简直是神器,能避免很多重复数据的破事儿。
  3. 字段映射要细心:从A库到B库,两边的表结构不一定完全一样,可能A库叫customer_name,B库叫client_name,在“表输出”或“插入/更新”步骤里,有个“数据库字段”的标签页,你得手动把左边的“流字段”(就是从“表输入”过来的字段)和右边的“表字段”一一对应上,别搞错了,不然数据就窜位置了,有个偷懒的技巧是,如果两边字段名完全一样,可以点一下“输入字段映射”按钮,让它自动匹配。

当情况复杂点时,比如要实时对比两个库的数据差异,可以用“数据库查询”步骤。

光是把A库的数据全盘搬到B库,有时候不够,你可能需要知道,哪些数据是B库有而A库没有的(需要补录),或者哪些数据两边都有但内容不一样了(需要更新),这时候,“表输入”还是负责从A库取数据,但接的不是“表输出”,而是一个“数据库查询”步骤。

这个“数据库查询”步骤会去连接B数据库,用它自己的逻辑(比如用主键)去B库里查找A库过来的这条记录,它会给数据流添加一个标记,是否在目标库中找到”,你后面可以接一个“过滤记录”步骤,找到”了,就走更新流程;没找到”,就走插入流程,这样就能实现非常精确的增量同步或者差异同步。(来源:Kettle社区中关于数据比对和增量同步的常见方案讨论)

聊聊Kettle里头怎么同时搞定俩数据库那些事儿和小技巧

再进一步,如果两个数据库需要“对话”才能完成一个操作,就得请出“作业”了。

“转换”像是车间里的一条流水线,干的是数据变形的活儿,而“作业”像是项目经理,负责调度一条条流水线,并且可以判断成功失败。

举个例子,你想把A库的数据同步到B库,但同步之前,需要先把B库的某张临时表清空,这个“清空表”的动作和“数据同步”的动作,就是两个独立的任务,你就可以创建一个作业,先放一个“SQL”步骤,连上B库,执行TRUNCATE TABLE清空表,再放一个“转换”步骤,执行我们上面说的那个数据同步的转换,作业会用箭头把它们串起来,保证先清空、再同步,有条不紊。

聊聊Kettle里头怎么同时搞定俩数据库那些事儿和小技巧

高级一点的小技巧:用“事务”保持步调一致。

这个稍微绕一点,但很重要,想象一下,你要同步一万条数据到B库,结果同步到第9999条的时候,B数据库突然抽风了,整个同步失败,那你之前同步成功的9999条数据怎么办?留在B库里会变成脏数据。

这时候,就需要数据库事务来帮忙,在Kettle里,你可以在“表输出”步骤的高级标签页里,勾选“使用批量插入”和“使用事务”之类的选项(不同版本可能叫法略有差异),它的意思是,Kettle会把这一万条插入操作打包成一个“事务”,只有在所有数据都成功插入后,Kettle才会向数据库发送一个“提交”指令,数据才真正写入,如果中途任何一条失败,Kettle会发送“回滚”指令,数据库就会把这期间所有插入的数据全部撤销,B库会恢复到同步之前的状态,就像什么都没发生过一样,这保证了数据的“原子性”,要么全成功,要么全失败,避免出现同步到一半的尴尬局面。(来源:关系型数据库事务概念在Kettle中的实现机制)

唠叨几句避坑的心得:

  • 连接池要设好:同时搞两个库,数据库连接是很宝贵的资源,在定义数据库连接时,好好设置一下连接池参数,比如初始连接数、最大连接数,设得太小,忙的时候不够用会卡顿;设得太大,又浪费资源,根据实际情况调一调。
  • 批量提交提效率:往数据库里插数据,别一条一条地插,那太慢了,在“表输出”步骤里,设置一个“提交记录数量”,比如1000条提交一次,这样能大幅减少和数据库的交互次数,速度能快上好几倍。
  • 日志一定要看:同步过程中万一出了错,别慌,第一时间去看Kettle的日志,它会非常详细地告诉你,是在哪一步出的错,错误信息是啥,很多时候问题就出在SQL语法、字段类型不匹配或者网络连接超时这些地方,仔细看日志都能找到线索。

在Kettle里搞定两个数据库,核心就是灵活运用这些步骤和技巧,像搭积木一样把它们组合起来,先从简单的“表输入”-“表输出”开始练手,慢慢再尝试更复杂的流程,多试几次就熟练了。