Datastage的使用心得及unix应用
Datastage是Ascential公司出品的著名第三方ETL工具。它的主要特点有:
1.可视化操作截面,避免了大量的手工code
2.第三方工具,善于处理复杂的数据源
3.可监控性好,能够快速发现ETL中的问题并解决
对于Datastage的初学者来说,通过学习官方培训资料(网上到处都有的当了),可以快速的入门,毕竟Datastage是一个可视化的工具,没有太深涩难懂的内容。但在真正运用中,就可能碰到各种各样的问题。下面就说一说我在使用中曾经困惑过的一些问题:
1.Job的粒度。一套ETL过程中,含有多个步骤,在设计过程中,到底是粗化一些,用少而复杂的job实现,还是细化一些,用多而简单的job实现更好呢?我个人认为,比较细的粒度更有利于程序的开发。在开发初期,表面看来细化的job比较繁琐,但在项目后期的测试阶段,细化的job可以更准确的定位错误并易于修改。
2.并行和串行。当到了开发后期,我们准备把多个job连接起来,我们就会发现,能否将多个job并行成为ETL效率的关键,而这个因素在设计初期往往被忽略。ETL中可能会涉及多个数据源的多个表,而多个job也可能会形成对某个数据源以及其中的某个表的争用。当数据源争用时,会影响ETL的执行效率。当表争用无法解决的时候,就只能使用串行。而一个好的结构流程设计,可以极大的减少这种争用,从而提高ETL的效率。
3.要将Datastage与外部code相结合。Datastage并不是独立运行的开发工具,它需要外部控制程序为载体,才可以进行良好的客户操作。而Datastage也不是万能的,简单的说,它只是sql语言的一个可视化载体。因此,有一些功能,并不一定要在Datastage中实现,而应该放到外部程序中,以sql code的形式完成,以保证整个程序的稳定性,安全性。
上面是一些大方向的问题,在实际中会有很多烦琐的小问题,我也尽量的列举一些:
1.字符集:output和input中的字符集都设置为none,是一个不错的选择。至少可以保证程序运行不会因为乱码abort。
2.文本中的列分隔符无法设置为三位,从理论上讲,只有三位分割符才可以保证程序不会将乱码辨认为分隔符,这是Datastage的一个缺陷。
3.在使用自定义sql前,需要使用非自定义形式手工配置好所需要的表,然后再切回自定义格式,如果直接写自定义sql,将导致Datastage无法辨别表名,从而导致错误,这应该是一个bug。
4.保持配置一个input或output,就view data一下的习惯,不要等到run时再回头找error.
5.Input中尽量不要使用insert or update之类的选项,它和insert only的差别是巨大的。使用insert or update等选项,相当于使用游标,逐条进行对比,每insert一条,都要先做一次全表扫描,其速度是可想而知的。如果必须要实现这种功能,应使用其他方法,如先delete目标表中所有与源表重复的记录,然后再从源表中insert数据.
6.Date型数据是比较麻烦的,因为Datastage中的日期格式为timestamp,当然你也可以把它的日期格式更改为date型,但经常会出现错误。对于oracle数据库源表和目标表,不需要对date型数据做任何转换,直接使用默认即可,但对于informix等一些数据库,则需要使用oconv,iconv函数进行转换,并在output中相应的修改output sql中的日期格式。具体用法可以去网上或查datastage帮助。
7.只要你保证input和output时数据类型和长度不会有问题,在两者之间的这一段过程中,Datastage中的数据类型和长度是可以随意更改的,也可以随意增加自定义列。
8.字符串中的半角空格需要用trimb,而不是trim函数,但这点往往被忽略。其他的情况还可能有半角中文等,所以字符串,长度,字符集,这几者之间经常会导致Datastage产生错误,所以应尽量保证insert前的字符串长度要小于insert后的字符串长度,而你看到的insert前的字符串长度并不一定就是它在Datastage中真正的长度,所以使用trimb函数在input sql中做一下限制,才是最稳妥的方法。
最后说一个datastage在unix中应用的实例,以供大家参考:
一个完整的ETL,其步骤是:
1.业务用户接口(java,jsp等友好界面)触发
2.Shell运行
3.启动Controljob运行
4.Controljob启动job
5.监控job状态的Controljob运行(循环运行,直到所有job结束)
6.返回job执行情况到shell
7.Shell返回执行情况到业务接口
8.用户得到结果
可以看出,这里包括了几个主要元素:业务接口,shell,controljob,getstatus controljob,job
其中只给大家列出controljob,getstatus controljob,以及shell中的controljob调度命令,其他的部分就不再详述了
一、普通的control job
1.带斜线、下划线并加粗 的部分需要考虑是否是并行的,如果是并行的就不需要这句
2.原始层需要加进蓝色的行
3.红色的表示job的名字,用来替换job的名字
* Setup DXrtInc, run it, wait for it to finish, and test for success
hJobDXrtInc1 = DSAttachJob("DXrtInc", DSJ.ERRFATAL)
If NOT(hJobDXrtInc1) Then
Call DSLogFatal("Job Attach Failed: DXrtInc", "JobControl")
Abort
End
Call DSExecute("UNIX", "/essbase/script/dwcorp/system/t.sh", Output, SystemReturnCode)
*If FAIL Then RESET
Status = DSGetJobInfo(hJobDXrtInc1, DSJ.JOBSTATUS)
If Status = DSJS.RUNFAILED Then
ErrCode = DSRunJob(hJobDXrtInc1, DS