赵贵兵
摘要:Kettle是一款功能强大且最流行的ETL工具,该文通过Kettle在工程实践中的一个应用场景,描述了Kettle应用方法和技巧,希望为其他应用提供参考。
关键词:Kettle;ETL;流程软件
中图分类号:TP311 文献标识码:A
文章编号:1009-3044(2019)09-0095-02
Pentaho公司的Data Integration产品,又名Kettle,是一款使用元数据驱动的功能强大的ETL工具,可以在Windows、Unix上运行。Kettle本身提供了强大的图形界面设计器和丰富的组件,可以大大缩短数据抽取项目的开发周期,并且容易维护。Kettle设计器界面友好,提供了工作流设计模式,能满足各种场景的实现,更详细的说明和下载请参考Pentaho官网:community.pentaho.com。
下面详细说明作者在实践中应用Kettle时遇到的问题和解决方法,希望能为大家的实践应用提供参考。
1 应用案例说明
在该应用中,需要准实时的将大量碎片文件中的行记录保存到数据库,并将部分记录分发给下游模块。文件中的行记录在入库前需要进行规整、转换、过滤、匹配、合并记录等复杂操作。下图是对一批文件的处理流程:
以下对该流程图中的重要组件进行说明:
1)“从结果获取记录”组件从父流程接收最多500个文件全路径,然后由“列出字段”组件解析出每个文件的行和列的值,解析出的每一行记录都保存有该行所在的文件名。如果该流程每次只接收一个文件,那么在需要处理大量碎片文件的情况下,根本无法满足性能要求,因为流程的加载和启动占了一次流程执行的绝大多数时间。
2)“Movefile Step”组件是一个自定义组件,该组件的功能是判断记录中传入的文件名如果发生变更,就将变更前的文件备份并删除。Kettle自带组件中没有此功能的組件,考虑到需要在很多流程中使用,所以利用了Kettle的插件机制,定义了该组件。
3)“记录输入格式错误”->“字段选择”->“Movefile Step”,“记录hit失败”->“字段选择”->“Movefile Step”,“记录入库错误”->“字段选择”->“Movefile Step”,“空操作”->“字段选择”->“Movefile Step”,以上这些流程确保了所有记录都会经过“Movefile Step”组件,从而保证当一个文件的所有行被处理后,这个文件一定会执行被备份和删除操作。
4)“字段转换”是一个JS组件,被使用对字段值进行规整,增加需要的扩展字段。JS组件在测试中达到4000记录/秒的处理效率,能满足该应用场景的使用需求。在该应用中,有很多个业务流程,它们是并行执行的,这样不同业务的碎片文件能够被并行处理。“Java Code”组件能提供更高的处理效率,但是编写的代码更复杂,在可以满足处理效率的前提下,“JavaScript Code”是更好的选择。
5)“关联外部资源”是一个“Java Code”组件,虽然该组件编写复杂,调试困难,但在这里使用它可以使流程绘制更简洁,因为这里的业务逻辑太复杂,使用Java语言更容易描述清楚。如果只是使用Kettle的自带组件,可能会绘出一条异常复杂的流程图。关于如何为“Java Code”组件编写代码将在后文中描述。
6)“关联外部资源查询”是一个“Java Code”组件,它将Kettle流中的字段值和内存中缓存的字典进行匹配,如果匹配成功,则将字典中对应的值填入Kettle流。在该应用中有多个内存字典,它们通过Job定时从数据库中加载到Kettle应用程序内存中,通过Java读写并发锁避免读写冲突。
7)“判断插入还是更新”是一个“Java Code”组件,它用于前后记录的匹配。在该应用中,有“开始”记录,有“结束”记录,还有其他记录,“开始”和“结束”记录根据某些字段值可以判定为一对记录,需要做合并。“开始”记录会被记录在内存中,当“结束”记录出现时,首先在内存中查找对应的“开始”记录,如果未找到则去数据库中查找。记录在内存中的“开始”记录,如果被“结束”记录匹配上则被清除,或者超过时限也会被清除,这些被从内存中清除的“开始”记录在数据库中仍然可以查找到,不会丢失。
8)“插入或更新数据库”是一个“Java Code”组件,它将一条输入记录拆分并插入多个数据库表,并保证多个表的事务一致性,它同时还将入库的记录通过自定义的Socket服务发生给Socket客户端。自定义的Socket服务在应用初始化时创建并接收客户端的连接。
在该应用中,所有“Java Code”组件中使用的数据库连接都是从c3p0连接池获取的,这样可以更好的管理和监控数据库连接。
上图的流程是一个实际应用中复杂ETL流程,它包含了许多典型的操作,如内存匹配、入库、通过Socket分发、备份并删除文件等。作者通过巧妙的使用Kettle中的各种组件,将复杂的操作过程简单化,在Kettle流程图中清晰的表达了出来,同时也彰显了Kettle的强大。
2 应用技巧
1)Kettle自带的“Java Code”组件是一个功能强大的脚本组件,为Kettle功能扩展提供了强力支持。如果直接在“Java Code”组件中编写Java代码,不但困难,而且容易出错。如果代码逻辑复杂,那么直接在Kettle界面上编写几乎不可行。一种方法是首先在IDE中编码,然后将代码同步到“Java Code”组件中。具体操作如下:
1)在IDE中新建一个Java工程,将Kettle安装目录下lib目录中的所有jar引入该工程。
新建一个Java类,该类继承Kettle的TransformClassBase类。
当在IDE中编写完成后,将Java类中“import”部分和“processRow”方法的代码拷贝到“Java Code”组件即可,如果除“processRow”外,还在该类中新建了其他方法,也要将这些方法一并拷贝到“Java Code”组件中。
2)“Java Code”组件中的Java代码和它引用的其他代码中不能使用Java模板类功能,如不能使用“java.util.List
3)从Kettle中配置的数据库中获取c3p0连接池所需的数据库信息,代码如下:
TransMeta transMeta = getTransMeta();
DatabaseMeta dm = transMeta.findDatabase(getVariable(“dbname”, “defaultName”));
String host = dm.getHostname();
String port = dm.getDatabasePortNumberString();
String db = dm.getDatabaseName();
String username = dm.getUsername();
String password = dm.getPassword();
4)Kettle插件編写和插件安装,请参考该文档:https://help.pentaho.com/Documentation/6.0/0R0/0V0。
5)配置log4j日志,将log4j日志配置文件如“log4j.xml”放在Kettle安装目录的classes目录下,重启Kettle即生效。
6)添加第三方jar包到Kettle中,最直接的方法是将jar包放在Kettle安装目录下的lib目录中,重启Kettle即可。
参考文献:
[1] Pentaho Kettle源代码.[EB/OL].https://github.com/pentaho/pentaho-kettle .
[2] Kettle安装目录/docs/English/welcome/index.html Kettle安装包包含的Kettle文档[EB].
【通联编辑:代影】