Kettle中ETL的效率优化
ETL效率优化
开启数据库日志记录及性能监控
如果我们想要优化一个ETL(KTR或者KJB)的性能,我们首先需要知道的就是它的瓶颈在哪里。而这些信息一般只能在ETL运行的步骤度量中看到,并且是不会持久化的。如果你希望把一些数据记录下来,帮助以后进行查阅,那么可以开启数据库日志和性能监控。
作业
Edit -> Settings -> Log
具体设置过程就不细讲了,很简单。
转化
Edit -> Settings -> Logging
这时开启了日志记录,还需要设置性能监控
Edit -> Settings -> Monitoring
勾选 Enable step performance monitoring(开启性能监控),下面的两个选项分别是:
Step performance measurement interval(ms) (对每一步进行性能监测的度量间隔):这一个选项的大小会影响你在数据库记录的详细程度,一般以运行总时长的十分之一左右的数值即可,这样对于每一步可以记录10组左右的数据,足够做一些基本的分析,注意单位是毫秒。
Maximum number of snapshots in memory(在内存中保存的最大的快照数量):这一个选项在我们系统的内存不是很足够时可以使用,但是太小可能会导致无法分析出来,和上面的选项搭配使用。
转化的错误日志输出
我们在运行过程中会输出大量日志,这样我们在定位问题的时候需要去日志里找出错的位置在哪里。Kettle中可以对KTR单独配置日志,如果我们把KTR的错误日志直接输出出来,那么在定位问题的时候就会非常方便,设置的方法如下:
在Job中,选择需要输出错误日志的步骤(经常出错或者可能出错的步骤),编辑,选择Logging,勾选Specfify Logfile(指定日志文件),选择路径、后缀,日志级别选择错误日志(调试时可以选详细或者行级)。
后面的选项:
Append logfile(追加到日志文件):该选项是指日志输出到已有文件中。
Create parent folder(创建父文件夹):该选项是指如果给定的路径中有不存在的文件夹会自动创建。
Include date in logfile:日志中包含日期。
Include time in logfile:日志中包含时间。
数据库优化
因为ETL就是对异构数据库中数据的处理,因此绝大部分性能问题都是和数据库相关,本节内容从数据库配置、ETL优化、SQL优化等方面进行讲解
数据库配置
连接池配置
数据库连接池在业务数据量比较多,而且短连接很多的时候适合配置。在这个时候,每次数据库连接建立和断开所花费的时间远长于进行数据库操作的时间,配置连接池可以更好的利用网络资源,将连接建立和断开的开销降低到最小。因此在大多数情况下,配置Kettle数据库连接池均可提高ETL的性能,如果没有配置连接池,那么在数据量大时候很容易出现Error Connecting Database Error。
该设置主要是在创建及管理连接的部分:
数据库连接 -> 连接池 -> 使用连接池
设置连接池的大小及相应参数,这些参数需要根据数据库实际情况及使用情况进行配置,可以咨询DBA。
数据库参数设置
在数据库连接的面板中,选择“选项”,(上面两个是普通和高级),在参数列表中,根据情况添加以下参数:
defaultRowPrefetch = 200; (default = 10)
这个参数是修改每次从数据库取回的记录的行数,默认为10,修改为200后可以减少从数据库取值的次数。
(Oracle Only) readTimeout = 60;
这个参数是修改从数据库读数据时的超时时间,单位是秒,将这个值改大一点可以防止大量数据读取时的超时问题
(Mysql Only) useServerPrepStmts=false;
rewriteBatchedStatements=true ; useCompression=true ;
前两个参数会让数据库重排Insert语句,合并多条插入语句成为一条,提交插入效率。第三个参数表示在传输时开启数据压缩 ,提高传输效率。这些在使用table output的时候很有效,在配置充足且网络正常的情况下应该可以达到20k~80k的写入速度。
ETL优化
提高数据库操作中的Commit Size
在写入数据库的时候,有一个Commit size的选项,这个值在默认的情况下是1,我们可以根据服务器的性能,将这个值改大一些,通常会改为100以上的值。这个值在写入量比较大的时候可以显著提升数据库的性能,但是并不是越大越好,通常范围在100〜10000,需要根据实际情况进行配置,具体数值可以根据性能监控的记录来确定。
这个值从1调整到合适值性能大约可以翻倍,一般情况下也有20%左右的效率提升。
Insert/Update增加错误处理步骤分离Insert和Update
Kettle的原作者在他的博客中提到过,尽量不要使用Insert/Update组件,因为这个组件慢的他都受不了,正常情况下在几百条每秒(对比TableInsert几万的速度)。如果必须使用这个组件的时候,那么可以在Insert/Update中勾选Don't perform any updates(不做任何更新操作),然后把错误的数据指向一具数据库更新的操作,这要就把添加和更新分离了开来。根据官网描述,在少量更新大量插入的时候性能可以提高到原来的3倍左右,实测时达不到,可能和数据集有关。
数据库分组和排序优于ETL分组和排序
在ETL中减少排序和分组的操作,尽量使用数据库完成排序和分组。在KTR中,数据是使用流的方式在不同的步骤间传递数据,使用排序和分组的操作会在这一步阻塞KTR的执行,直到接收到前面所有步骤传过来的数据为止,导致ETL的运行时间增长,占用的内存增大。
使用Blocking Step也会将流阻塞到这一步,和以上情况类似。
调整步骤之间的缓存
KTR是一个流式的处理过程,步骤与步骤之间的数据传递是通过缓存来完成的,调整缓存的大小可以对KTR的运行产生明显的影响。
Edit —> Settings —> Miscellaneous —> Nr of rows in rowset (缓存的记录行数)
这个值的大小需要根据机器的配置来选择,如果可用内存足够,一般的设置是10000,也就是缓存10000行数据,如果内存比较紧张,可以将该值调小一些,保证不会占用过量内存。
在性能监测时,这也是一个用来找到瓶颈的核心参数。如果某一步的输入和配置的缓存大小接近,但是输出很小,那么这一步就是性能的瓶颈。如果缓存大小配置了10000,但是几乎所有步骤的输入输出都只有很低的一个值,比如50,那么,性能的瓶颈就是输入。
延迟转化
很多字段在读入到最后输出,实际上都没有被操作过,开启延迟转化可以让kettle在必要的时候再进行转化。这里的转化是指从二进制到字符串之间的转化,在输入和输出都是文本的时候更为明显。事实上,Select Values在转化的效率上也高于读取时直接转化。
使用复制并行处理某个步骤
现在的机器都是多核的,使用多CPU并行处理对CPU使用密集的步骤可以提升ETL的执行效率。
在需要并行处理的步骤上,选择Change Number of Copies to Start, 修改这个值为小于机器核心总数的一个值,一般2〜4就可以满足要求。
KTR中,尽量减少步骤的数量
步骤的数量会在影响KTR的执行效率,包含并行处理时复制的数量。KTR中步骤的数量为机器核心总数的3〜4倍最佳,如果超过这个范围,可以考虑通过减少步骤数量的方式以提高KTR的执行效率。
不要在Select Values的步骤删除某个字段
如果在Select Values的步骤删除某个字段,kettle会需要调整现有的存储结构,在可以不删除的时候尽量不要删除字段。
SQL优化
这部分和所有使用到数据库的地方一样,优化查询语句,优化表结构设计,添加合适的索引等。
其它优化
- 使用Carte管理KJB和KTR减小内存消耗
- 使用定时器定时处理
- 使用集群并行运行
- 使用数据仓库及缓慢更新进行同步增量更新
总结
总体来说,这部分的内容主要就是数据库配置的优化及ETL本身的优化,当然在提高效率的时候也要兼顾资源的使用情况,有的方法可以提高效率,但是会消耗更多资源。因此我们需要综合考虑,通过一些合理的方式既能充分的利用资源,又不会因压力过大影响业务的正常进行。
ETL可以看作是一个可视化的、数据处理领域的编程工具,因此,ETL编写过程不仅需要了解业务,还需要一些数据库方面的知识进行支持,如果写出来的ETL效率低下,运行时间长,吃资源多,那么,是时候需要考虑优化一下ETL了。.