Solo  当前访客:1 开始使用


一个hadoop container内存不足的问题

背景

目前项目组在负责 load 一批数据到线上的图数据库,为了验证写入到 DB 里面的数据质量,写了一个 tool 去比较每个 account 以及出入边的数目是否跟原数据一致。

程序的逻辑:

Map 阶段:读取源文件,以每一个 account 作为 key,本身实体作为 value,写 context。

Reduce 阶段:对于每一个 account,从 list 计算出边、入边数目,同时查询 DB 验证是否一致。

问题

在少量的数据下测试完全没有问题,但是一到大数据集,MapReduce 在 Reduce 阶段就会卡在 70% 多的阶段,然后会有很多 reduce 失败,最终导致整个 job 失败。

调查

Reduce 处理的数据太多了?

基于这方面的考虑,我做了两个优化。

首先我发现我的目的是为了统计,在 reduce 阶段只需要知道总的 count 数目,并不需要太多关于实例的东西,因此就把 map output 的 value 由原来笨重的实体换成了统计数据:这个点出边多少,入边多少。

基于上述优化的基础上,我在 map 和 reduce 中间阶段加入了 combiner 逻辑,直接在 combiner 阶段,对统计先进行了汇总。

在性能上,让 job 的速度有了很大提升,但是实际问题还是没有解决。还是会有 failed Job。

存在内存泄漏?

在做完上述两个步骤之后,整个 reduce 的工作应该已经很轻了:汇总一下出入边的数目和查询两次数据库。但是还是提示说 physical memory 不足。而且 reduce 迭代的过程中,我也没有缓存数据。我就怀疑有内存泄漏的问题。

用了个 for 循环在本地跑了 reduce 的逻辑,看见内存果然还是不断的涨。

对比两次 heap dump,发现增长最大的 instance 是 char[], long[]。对照又梳理了一遍程序,大概知道为啥 long 和 char 会很多。char 是 reduce 写结果数据的,long 是用来统计数目的。他们的释放也不存在问题。倒是发先 GremlinQueryEngine 每次查询都 new 了一个,特别浪费。把它抽取出来成为类的一个 field。之后速度有明显上升。问题还是存在。

调大 Reduce 的内存?

问题困惑不解之时,咨询了 team 的架构师,建议是加大内存试试。把 reduce 内存调到了 12G,Java 内存调节到了 10G。

-Dmapreduce.reduce.memory.mb=12288    \
-Dmapreduce.reduce.java.opts=-Xms10240m -Xmx10240m     \

再次跑程序,没有出现上述错误。经过分析,在我们数据库里面存在有万分之 3 的极大点,它的单边数目达到 30 万加。在查询这些点的时候,还是会把所有的 partition 都读取过来,算一个 count,这个是非常耗内存的。


标题:一个hadoop container内存不足的问题
作者:wuhaifengdhu
地址:https://wudevin.cn/articles/2020/02/21/1582269267598.html
只有站在峰顶的人,才能看见星辰大海。
新一篇: 博客证书升级<阿里云版本> 旧一篇: Solo博客升级