hive – parquet文件格式OOM问题

sqoop import导入mysql表时,为了降低磁盘空间占用,均采用了parquet文件格式进行列存储+压缩。

然而,发现后续执行hive sql时会频繁出现OOM,大部分集中在mapper,少量reducer也会OOM,其报错大概如下:

running beyond physical memory limits. Current usage: 1.1 GB of 1 GB physical memory used; 3.9 GB of 4.2 GB virtual memory used. Killing container。

其实上述报错就是说物理内存使用超过了1G上限导致OOM,共使用了3.9G的virt虚拟内存(malloc的总量)还未达到4.2GB的上限。

SQL不复杂,为什么OOM呢?Hive执行的MapReduce内存限制默认是多少呢?我们应该关注MapReduce的默认内存限制么?下面说说。

原因

parquet是列式存储,会每N行作为一个group,这个group内按列排布并压缩。

parquet因为按组压缩与解压,因此至少需要将待解压和待压缩数据全内存存放,因此当MapReduce同时读写多个文件时,会在内存维护多个文件压缩缓冲区,导致默认的内存空间不足。

因此,我们要理解Hive的内存限制到底在哪里,是什么关系。

Yarn容器内存限制

在hive命令行,可以查看yarn配置的容器内存限制:

hive> set yarn.scheduler.minimum-allocation-mb;
yarn.scheduler.minimum-allocation-mb=16
hive> set yarn.scheduler.maximum-allocation-mb;
yarn.scheduler.maximum-allocation-mb=262144

这就是当前yarn允许给容器申请的内存范围为16MB~262GB之间,可以说yarn是没有限制容器申请的内存大小的

MapReduce内存限制

MR是yarn上的一个应用,它会向yarn申请mapper容器和reducer容器,这时候申请的容器内存大小也是可以配置的。

在hive下查看:

hive> set mapreduce.map.memory.mb;
mapreduce.map.memory.mb=1024
hive> set mapreduce.reduce.memory.mb;
mapreduce.reduce.memory.mb=1024

上述配置说明,MR默认申请的yarn容器内存就是1024MB,只要跑在里面的程序别超过1024MB就不OOM,这就是上面的1.1 GB of 1 GB physical memory used;的来源

至于3.9 GB of 4.2 GB virtual memory used. Killing container 呢?它其实受到yarn对虚拟内存大小的限制:

> set yarn.nodemanager.vmem-pmem-ratio;
yarn.nodemanager.vmem-pmem-ratio=8

如果malloc的总内存超过容器申请内存的8倍,即便物理内存没有超过限制,也会杀死容器。

JVM内存限制

一开始我将set mapreduce.map.memory.mb=4096,set mapreduce.reduce.memory.mb=4096,发现仍旧OOM。

后来才得知,yarn容器给了4GB没问题,但是我们没有让运行的Mapper和Reducer程序的JVM内存调高,所以压根用不完容器的4GB内存空间。

可以修改一下hadoop配置文件(记得分发到集群),或者hive临时设置一下:

set mapreduce.map.java.opts=-Xmx3686m;

set mapreduce.reduce.java.opts=-Xmx3686m;

这里让JVM的内存上限大小大约是MR容器申请内存的85%,因为容器除了跑JVM程序外还需要留一下Native的内存空间,这和K8S上跑JVM程序是一个道理,只不过现在是Yarn容器。

在比较早的Hadoop版本中,上述2个配置可以写为1行,新版本hadoop仍旧保留了对该选项的兼容:

set mapred.child.java.opts=-Xmx3481m;

总结:Hive SQL翻译的MR任务不会有无限使用内存的情况,除非写的SQL不合理。

parquet文件OOM的原因仅仅是因为默认的内存限制太低,而parquet文件格式对内存空间的要求又比较高,所以导致了问题。

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~