如何在运行Hadoop时避免OutOfMemoryException?

14

我正在处理1.5TB数据的Hadoop作业,并且需要进行大量的模式匹配。我有多台机器,每台机器都有16GB的RAM,但是当我使用Hive运行此作业时,总是出现OutOfMemoryException的错误。

我想知道如何在文件hadoop-env.sh中最优地设置选项HADOOP_HEAPSIZE,以便我的作业不会失败。是否有可能设置此选项,使得我的作业不会失败呢?

当我将HADOOP_HEAPSIZE设置为1.5 GB并从查询中删除了一半的模式匹配时,作业成功运行。那么,如果这个选项不能帮助避免作业失败,它的作用是什么呢?

我本来打算做更多的实验来确定最佳设置,但由于这些作业需要运行>10小时,所以我请求你的建议。


你觉得 HADOOP_HEAPSIZE 为什么不能帮助避免失败?根据你的经验,它似乎能够做到。由于只有通过检查你的数据/作业才能知道具体原因,你的情况需要至少这么大的堆大小。你能否重构你的作业,使其不需要如此大的堆? - matt b
我修改了我的工作,所以它不再使用如此大的堆,但同时我也改变了 HADOOP_HEAPSIZE。但是我并没有看到实际的结果,我的意思是:为什么要将堆设置得比:我的RAM数量/映射器或减速器的数量还小呢? - wlk
1个回答

13

你的工作失败了还是服务器崩溃了?如果你的工作因为节点上的OutOfMemory而失败,你可以调整每个节点的最大映射和减速器数量以及JVM选项,这样就不会再发生了。mapred.child.java.opts(默认为200Xmx)通常需要根据数据节点的特定硬件进行增加。

http://allthingshadoop.com/2010/04/28/map-reduce-tips-tricks-your-first-real-cluster/

可以在NameNode上设置最大任务数,也可以在可能具有不同硬件配置的数据节点上覆盖(并设置为最终值)。最大任务分别设置为mappers和reducers。计算此值基于CPU(核心)和RAM的数量以及您在mapred.child.java.opts中设置的JVM最大值(默认为200)。Datanode和Tasktracker各自设置为1GB,因此对于8GB机器,mapred.tasktracker.map.tasks.maximum可以设置为7,mapred.tasktracker.reduce.tasks.maximum可以设置为7,而mapred.child.java.opts设置为-400Xmx(假设有8个核心)。请注意,如果只有1个CPU和1个内核,则这些任务最大值由您的CPU执行,那么是时候为数据节点获取新硬件或将掩码任务设置为1了。如果您有1个CPU和4个内核,则将map设置为3,reduce设置为3会很好(为守护程序节省1个内核)。

默认情况下只有一个reducer,您需要将mapred.reduce.tasks配置为多个。该值应该介于每个节点的最大任务数乘以数据节点数的0.95至1.75倍之间。因此,如果您有3个数据节点,并设置了最大7个任务,则应将其配置在25到36之间。

如果您的服务器因OutOfMemory问题而崩溃,那么这就是HADOOP_HEAPSIZE的作用,仅适用于进程堆(而不是任务执行)。

最后,如果您的工作需要很长时间,您可以检查是否有另一个好的配置添加项是mapred.compress.map.output。将此值设置为true应该可以(在压缩和传输时间之间平衡)大大加快Reducer的复制速度,特别是处理大型数据集时。通常任务确实需要时间,但也有一些选项可以调整以帮助加快速度=8^)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接