一次kettle性能优化

将2.04G的数据导入到mysql数据库中,数据格式是json格式,由于包含不同类型的数据,需要将不同类型的数据进行拆分操作,提取出目标数据。其中涉及值替换,json解析,字段选择等操作。刚开始运行的过程发现很慢,而且解析到最后出现OOM的情况,完全崩溃,运行了几个小时OOM了,泪流满面。

既然OOM,当然第一想到的是,那肯定内存不够啊,立马给加内存。好歹也学了一段时间深入虚拟机内存,打开jvisualvm,通过visualGC看各个区域的内存占用情况。事实证明还是too naive。内存占用居然超过了13g,而且基本上是处于old区。大部分内存占用得不到释放,dump出来的prof也显示基本是char[]数组的数据。此时才想起我应该注意一下执行步骤,果真还是太年轻,没经验,执行步骤基本上卡在json input那一步,导致大量的数据读入进来之后,json解析处理不及时,数据堆在json input的上流,最后只好oom了。

既然定位出瓶颈在哪,就好办些。但是怎么优化json解析速度呢?此时就需要万能的google大神上场了。原来json input是通过javascript脚本实现的,性能上肯定比不上java的实现。还好,graphiq的一位工程师开源了,他们自己写的插件FastJson。作者在这篇博客中做了详细的性能对比和分析。同时,FastJson还支持移除源字段,以便解析完释放内存,还有支持对不存在字段的处理,设置default为null。插件github开源地址,但是作者是基于5.0.9 kettle-core编译的,笔者无法直接使用,只好下载代码自己编译,笔者使用的kettle-core版本是6.1.0.1-169,同时增加了swt,commons-vfs2的包,所以做了如下修改:

    <dependency>
            <groupId>pentaho-kettle</groupId>
            <artifactId>kettle-core</artifactId>
            <version>6.1.0.1-196</version>
        </dependency>
        <dependency>
            <groupId>pentaho-kettle</groupId>
            <artifactId>kettle-engine</artifactId>
            <version>6.1.0.1-196</version>
        </dependency>
        <dependency>
            <groupId>pentaho-kettle</groupId>
            <artifactId>kettle-ui-swt</artifactId>
            <version>6.1.0.1-196</version>
        </dependency>
        <dependency>
            <groupId>pentaho-kettle</groupId>
            <artifactId>kettle-test</artifactId>
            <version>6.1.0.1-196</version>
        </dependency>
        <dependency>
            <groupId>pentaho</groupId>
            <artifactId>metastore</artifactId>
            <version>6.1.0.1-196</version>
        </dependency>
        <dependency>
            <groupId>com.googlecode.json-simple</groupId>
            <artifactId>json-simple</artifactId>
            <version>1.1</version>
        </dependency>
        <dependency>
            <groupId>jsonpath</groupId>
            <artifactId>jsonpath</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>1.2.0</version>
        </dependency>
        <dependency>
            <groupId>net.minidev</groupId>
            <artifactId>json-smart</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>net.minidev</groupId>
            <artifactId>asm</artifactId>
            <version>1.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-vfs2</artifactId>
            <version>2.1-20150824</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.swt</groupId>
            <artifactId>org.eclipse.swt</artifactId>
            <version>3.1</version>
        </dependency>

然后就是愉快的按照作者的方式打包插件。等等。。好想忘了什么事,插件?怎么安装插件啊?还好领悟能力可以,直接放到plugins目录下,怎么找不到新的插件啊?笔者摸索了半天,才发现自己需要重新启动kettle,先前一直是通过快捷方式启动,不知道怎么回事,就是一直看不到,然后到安装目录中重新启动,果断看到了FastJson。泪奔啊。。。。

但是好像没有我预想的那么快,不过解析速度还是比json input快些的。发现瓶颈基本上还在Json解析这块。想想不对啊,这么慢的东东,不可能那么多人用,肯定还有什么地方不对。果断google了一下,kettle性能优化。发现了问题。原来我是暴殄天物啊,所有步骤都是一个线程在运行,人家可是支持多线程的。你这不是浪费资源吗?果断右击步骤 -> change number of copies to start..”并输入合适的线程数8(笔者的电脑是8核的),有些步骤会提示得现增加一个dummy才能修改线程数,直接按照提示操作即可。至此,重新启动转换,发现速度立马飙升上去了。性能瓶颈基本上的数据库写入上了。

那么数据库我们还能不能优化呢?由于笔者这里都是插入操作,就去看了下表结构,果断去除索引。其实到此,笔者已经较为满意,原先3,4个小时的导入,半个小时不到就搞定了。

还有个能够优化的地方,鉴于环境限制,笔者还没有去实践,那就是上集群。有兴趣的朋友可以去试试。。。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 106,249评论 12 126
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 143,990评论 18 618
  • window/show view / 找到svn资源库,显示查看项目属性中svn版本控制,找到url在svn资源库...
    玲珑花阅读 958评论 0 0
  • 宋秀红 (开篇) 非常荣幸有机会和自治州群教办的各位领导、同志一起学习、探讨、分享公文写作的一些心得和...
    香露草阅读 131评论 0 2
  • 生,如一场梦。 带来那所谓的,悲伤,烦恼,忧愁的夜。 却又让那黎明,冲散这一切。 白天,黑夜,交织着生活的悲与喜。...
    无言心阅读 39评论 0 0