将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个小时的导入,半个小时不到就搞定了。
还有个能够优化的地方,鉴于环境限制,笔者还没有去实践,那就是上集群。有兴趣的朋友可以去试试。。。