接着上篇文章说的事情。
所有bug解决完了,终于可以开始导数了,导数也很顺利,但是发现了一件不太舒服的事,速度怎么这么慢!!!
之前的速度一般为2w-3w/s,1000w的数据需要300s-500s,差不多5-10分钟,是可以接受的但是现在不到7000/s,不能接受,还是需要优化。
之前写过一篇很简单的优化oraclereader。提高channel的数量,多个任务去读取,但是看了hdfsreader的split的方法,这个切分就是根据文件个数切分的。
又要提到上次的任务了。
vendor_site表9578067数据 当时splitPk了,最后形成了50个小文件
而vendor_concat 8198714 一个文件。
很明显 如果我们在生产hive的数据文件的时候拆分为多个小文件,那么在读的时候无疑是能提高速度的。
那我就是一个大文件呢?那么还是一个任务能不能开启多个线程读这一个文件呢,感觉是可以的。本人水平有限。。。。看了下orcFileStartRead中orcInputFormat 没看到从指定offset读的。。。
那么会不会是写的慢呢,据说postgresql性能不咋地。。。
看下日志说明。
其中任务总耗时1439s ,读写任务都花了1400多秒。但是wait_read_time=70s 但是wait_write_time花了1340s
这个是啥,wait_write_time = 每次push的等待时间,也就是说这个queue一直是满的,或者消费的慢了,我在等postgresql插入上批数据,
说明了啥??? postgresql消费能力不足,太垃圾了。
那么怎么解决。1.增加postgresql的消费能力,2.增加memoryChannel的容量。
1先看下memory的代码
capacity=512, byteCapacity=64M
while (memoryBytes.get() + bytes > this.byteCapacity || rs.size() > this.queue.remainingCapacity()) {
notInsufficient.await(200L, TimeUnit.MILLISECONDS);
}
再看下postgresqlwrite代码,扎回事小老弟,这么慢
那就是2048条数据或者是数据总量>=32M的时候 就会flush
channel 512条数据 || 64M
writer 2048|| 32M
这两个看起来就不太对。。。 仔细思考下。
1.算了 先把channel的512搞大点。。直接2048.
对比 vendor_site 336->292 vendor_contact 1216->1127说明啥,是优化了一点,但是并没有什么卵用。但是channel这个参数调大应该没啥坏处 除了oom暂不考虑。
2.那么开始调整postgresql的参数,会不会是batch的数量太少了,2048确实有点不够看。 直接4096
大文件任务 从1216s->1127s->945s 提升了4分之1的速度,但道理再往上加batch还可以提速的。我以前测过mysql的batch大概在几万的时候速度是最快的。。。。。
总结下,
1.读取数据到hdfs的时候尽量使用多个channel,形成多个小文件。
2.增加channel容量没啥用,因为瓶颈在postgresql插入那里
3.增加postgresql的batchsize
4.增加hdfsreader的吞吐,没必要,瓶颈不在这。
5.关闭自动提交(autocommit=false),还没看源码。
6.COPY 命令可以快速的导入数据到postgresql数据库中,文件格式类似TXT、CVS之类。适合批量导入数据,速度比较快。注意COPY只能用于表,不能用于视图 https://www.cnblogs.com/xiaodf/p/5027196.html。 这个就需要hdfs导出为 csv后再导入到post 还要改源码
以上方式都可以尝试,如果帮到你,或者给你灵感,点个赞