首页 > 代码库 > ODI性能问题

ODI性能问题

 

  

在这里分析下最近分析和解决ODI性能问题的点滴,用作参考。在介入该问题前,已经具备的基础知识包括了ODI基础,SOA理论和实施,特别是04年封闭四天的informatic ETL培训和实操。几年的开发经验和技术积累。

首先我们拿到的问题是ODI性能慢,要知道ODI本身核心还是是ETL,只是ODI已经由传统的ETL转化为了ELT,先Load数据然后再进行转换。同时增加了声明式设计,正是由了声明式设计ODI才能够真正转化为按需,按参数调度的数据服务,更好的和SOA进行集成。

以往的经验始终有用,只是你无法预知会在将来的什么时候用到,即时你忘记也容易快速熟悉起来。

当拿到ODI性能慢的问题的时候,首先还是问题定义,是如何一个慢法,50万条数据要1小时?那么这个速度是否慢?我们是否有基于某种软硬件环境下的标准Benchmark数据。注意硬件配置,软件环境,源和目标的数据库类型,网络带宽都是我们需要分析的内容。任何问题的定义都必须要一个十分明确的场景。

任何问题的定义都必须包括外在场景,脱离场景即无所谓问题。

在我们确认软硬件环境都没有问题后,再获取同类型场景下的参考值一般为10分钟左右,那就明显存在ODI性能问题。确认性能问题后接下来要做的就是确认出现在ETL整个过程的那个阶段,是抽取,转换还是Load过程中慢。在这里首先进行如下分析:

由于我们ODI抽取的是视图,视图涉及到复杂的关联查询,所以最开始怀疑是视图查询慢引起的,同时看ODI整个步骤,发现是LOAD环境慢(在这里犯严重经验性错误,误认为了Load是从源端抽取数据的过程)。后面我们对视图进行了优化,效果还是不明显。

定义问题涉及到问题的分解和边界定义,分而治之和假设验证始终是缩小范围的关键。

为了进一步确定和视图不相关,将源端的视图换成实体表再试,发现仍然很慢,基本确认和视图无关。在整个过程中我基本还没有进入到ODI设计器查看详细的ODI设计过程。在确认了和视图关系不大后,进一步在网上搜索资料,发现三个点影响到ODI本身的性能。一个是KM知识模块的选择,一个是Agent代理最好放到目标,一个是最小化日志记录,调整批大小等。

对最小化日志记录和批大小再进行调整和测试,问题仍然没有解决。排除掉两个。由于目标端是生产系统,要在目标数据库端安装相应的Agent是相当困难的,到了这里感觉问题的解决必须要详细学习ODI产品和整个ETL实现过程,否则很难再深入的去解决该问题。

任何经验性判断都有可能形成误导或走入错误分支,唯一方法是要对提出假设尽快验证。

到了这一步后,必须要学习ODI了,原来都是理论和象征性的了解了些ODI,已经ODI和SOA服务集成的方法。那必须得进一步补充相关知识。这个时候开始搜索ODI资料,上Oracle官方网站查找ODI相关用户手册,再次感觉百度文库是个好东西。我在百度文库基本上可以下到ODI产品手册,用户手册,技术说明,详细的操作例子方法等,差不多有10多个文档。对这些文档进行大量的泛读后将关注点停留到两个详细的ODI操作手册上面,仔细看了一遍后对ODI的物理架构,逻辑架构,知识模块,接口,调度这些就有了基本的理解。在这里感觉到04年学习过得ETL知识完全可以用上,所以再熟悉这个的时候很容易。

解决问题很多时候受时间约束,核心技能包括互联网搜索,大量泛读后快速定位和精读深入。

第二天马上进入到ODI设计环境,对相关的有性能问题的ODI调度进行分析,详细从物理架构,逻辑架构,知识模块,包,接口看了一遍。进一步理顺这些功能模块的内在耦合关系,明确ODI设计的一个完整步骤。只有这个完成后才能够进入到知识模块影响性能的进一步分析。

本次为Oracle到Sybase的数据同步,查看使用的知识模块为SQL to Sybase而没有使用另外一个SQL toSybase(BCP),那就有必要搞清楚两个知识模块的区别,特别是Sybase数据库基本原来没有用过,又到网上查询资料和分析,得出官方结论是对于大批量的数据传输根本不推荐SQLto Sybase而推荐BCP方案。因为BCP是Sybase推荐的批量数据导入方案。

再一次进入到执行调度过程,对原方法的调度过程进行查看,发现Load过程用时间最久,在调度台可以看到具体的执行的命令和SQL语句,发现Load过程其实已经是完成了从源表取数据超目标的一个临时表插入的全过程。显然不是我原来理解的仅仅从源端查询出数据的时间。(进一步纠正错误假设)

走到这里基本明确一个正确的方向,即需要尽快对BCP方案进行测试和验证。那么把ODI中的LKM知识模块切换到BCP方式再试验,发现报异常。看来启用ODI不是简单的事情,又需要到网上查询资料查看BCP启用的一些基本条件,最终确定要做的事情包括:

1.需要在代理机器安装Sybase Open Client,因为BCP应用在这个包里面。ODI也是调的这个外部程序。
2.需要目标数据库打开select into/bulkcopy设置。

第三天,安装Sybase OpenClient,安装完成后终于找到BCP应用,重新对配置文件进行了修改,让BCP应用能够调用到正确的路径。这些都做完后至少BCP应用已经能够成功找到。也基本理顺BCP方案的整个过程,即首先是通过Oracle自身的unload将数据存为文本文件,然后再调用BCP应用将数据导入到Sybase数据库。(逐步清晰)

首先对于unload数据到文本文件,又出现乱码问题,基本判断为字符集原因,直接对LKM知识模块该步骤的内容进行查看,看了字符集设置不正确,修改导出代码为utf8后问题解决。

对于BCP导入也发现大量问题,首先就是服务器或数据库不存在,又进行了相关参数配置。然后发现BCP导入发生Unexpected EOFencountered in bcpdatafile的异常。这个问题基本又折腾我一天,不得不对BCP各个参数进行详细的学习,发现虽然对字段分割符,行分割符都进行了正确设置仍然无法成功导入而报错。(柳暗花明,在将要解决边缘往往更难熬,一个技术问题卡几天都正常。)

如果一个表能够成功导出,那么也应该能够成功再导入。(英文搜索一大堆也解决不了后,寻找新假设和途径)到这一步后,首先使用BCP对表数据进行导出,然后再导入一切正常。发现这里基本没有显性化设置相关分割符。BCP导入默认制表符为字段分割符,默认换行符为行分割符。那么如果我文本文件也能够按该要求输出,则应该就能够成功导入。再次修改unload程序设置字段分割符和换行符,修改完成后BCP导入基本成功。

到这里基本只剩下最后一个问题,即BCP导入的数据出现乱码问题。现在sybase数据库字符集编码为cp936,但是我导出文件编码为utf8格式,所以必须要转换。通过BCP增加参数显性转换后发现仍然导入报错误。还得搜索资料,搜索后发现还需要对客户端一个配置文件进行修改(还得搜索),修改完成后数据可以成功导入。

到了这步,基本只剩余一个遗留问题,即如果数据里面本身还有制表符这个不可见字符,那么导出的数据再导入将报错。这个问题需要在视图中进行处理,将制表符替换掉,如果这样基本就不会再有问题。

BCP全部调试通过后开始测试,对于50万条数据需要7分钟即可以执行完成,时间基本都花在BCPLoad过程上,但是仍然发现unload过程仍然花费了近1分钟,再次对unload脚本的批大小调整为3000再测试,差不多6分钟即可完成50万条数据的传输,整个方案应该有效和可行。

ODI性能问题