Kettle运行限制

Kettle是一个应用广泛的ETL工具,支持大数据量肯定是没有问题的,但是最近在做一个项目时,压力测试阶段总是出现莫名奇妙的问题,经过不懈努力总算是解决了,下面把遇到的问题介绍如下,供兄弟姐妹们参考:

1. 运行过程中收到 java.lang.OutOfMemoryError: Java heap space 错误
这个错误主要是Java的内存不足(heap space:堆空间)造成的,这个问题有时候无法避免,因为数据量就是那么大。解决这个问题有两个方向:
a. 给Java分配更多的内存,方法是:打开kitchen.sh/kitchen.bat,找到”OPT=”$PENTAHO_DI_JAVA_OPTIONS -cp …… ” 改为”OPT=”-Xmx4096m -cp …… ”
看到了吗,缺省512m,我一狠心给它改成了4096m,就是4G啦。我手头的这个服务器有64G的物理内存,改成4G不过分吧?所以用这个方法就已经无敌了。
b. 把“源数据库->目的数据库”的转换(Transformation)拆分为“源数据库–>文本文件”和“文本文件–>目的数据库”两个转换。(尚未试验,但据下面的这个帖子所述应该可以解决问题:http://forums.pentaho.com/archive/index.php/t-68806.html

2. 没有错误,运行到读或者写数据时一直在等待,小数据量没问题,大数据量才会出现问题
这个问题确实很费解,经过n多试验发现了问题的根源在Transformation的设置,如下图所示,要把Nr of rows in rowset设置为足够大,最好是你能用到的数量级后面加个0吧。我试验的是15W左右的数据,但是当时的设置时10W,我发现目的数据库的数据量停留在了100001不再增加了,于是就联想到了好像在这个界面看到了一个100000的东东,无论多么费劲吧,问题解决了总是值得欣慰的。猜想一下这个设置,可能是Kettle的设计者希望能预先知道最大会有多少数据,以便做相应的准备工作吧。另外,顺便说一下这个窗口里面的Feedback size,指每多少条记录会有一个信息提示出来,以便你知道进度。

定时运行Kettle任务

下面是用文件方式保存Job和转换时,在Linux运行一个Job的示例:

代码:
./kitchen.sh -norep -file “/root/Desktop/kettle_demo/demo_job.kjb”

注意:Linux环境中,当使用了自定义插件时,必须在Kettle所在目录下运行以上命令,否则会提示找不到自定义的插件。

当使用文件方式(norep)保存Job和Transformation定义时,Job中的Transformation路径要用下面所示的格式,否则会Job会找不到Transformation

代码:
${Internal.Job.Filename.Directory}/demo_transfer.ktr

定时自动执行:
编写一个shell文件:test.sh

代码:
CUR_PATH=$(cd “$(dirname “$0″)”; pwd)
PDI_HOME=/root/pdi-ce-4.1.0-stable/data-integration/
export JAVA_HOME=/usr/java/jdk1.6.0_21/jre
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
cd $PDI_HOME
./kitchen.sh -file=”$CUR_PATH/ascm_data.kjb” >> “$CUR_PATH/kettle.log”

run_ascm_job.sh
然后赋予该shell的执行权限:

代码:
chmod +x ./*.sh

添加自动执行命令:
登录Linux终端,运行crontab -e编辑Linux的定时任务文件:
添加如下一行:

代码:
25 * * * * /root/Desktop/kettle_demo/test.sh

表示在每个小时的第25分钟运行该命令
该定时任务的格式是:<分钟> <小时> <日> <月> <星期> <要执行的命令>
不限的条件就用*表示

运行 service crond restart重启crond服务,接下来等到定时的时间,看一下是否执行了。

如果运气好的话,就应该一切如愿了。

 

简单方法搞定日期格式转换的问题

    程序中经常会用到日期和字符串之间的转换,由于计算机的区域设置(日期格式设置)的不同,会导致在A计算机上运行正确的程序在B计算机上就出问题。如何搞定这些问题?
    字符串–>日期的转换:StrToDate函数,这个函数有两个实现,分别是:
      StrToDate(const S: string): TDateTime
      StrToDate(const S: string;const FormatSettings: TFormatSettings): TDateTime;
      如果我们的字符串格式是固定的话,如yyyy-MM-dd,用第一个的话,会很容易在不同日期格式设置的计算机上出问题。所以要用第二个,但是FormatSettings这个参数怎么设置呢?
      var
        FormatSettings:TFormatSettings;
      ————————————————-
      FormatSettings.ShortDateFormat := ‘yyyy-MM-dd’;   // 这里设置成和字符串中的日期格式一致的格式
      FormatSettings.DateSeparator := ‘-‘;
      FormatSettings.LongDateFormat := ‘yyyy-MM-dd’;    // 这里设置成和字符串中的日期格式一致的格式
      如何保证由日期转换出来的字符串的格式是固定的呢?用 FormatDateTime(‘yyyy-MM-dd’,date);

    日期–>字符串的转换:
      除了上面提到的可以转换成固定格式的字符串外,有时候其实我们是想转换成计算机的缺省日期格式(事先无法知道目标计算机的日期格式,比如说,我们要拼一个SQL语句,这里面的日期格式最好就是和计算机一致的,否则可能会在数据库里进行自动转换成日期的时候出错,这种情况我们只需要用DateToStr(date)就行了。
      顺便说一句,Access数据库中SQL语句里表示日期的话需要前后都加上#,而不是SQL Server等数据库里前后加单引号(自动由字符串转换为日期)。

I.DO