记一次MR报错:Container is running beyond physical memory limits...

本文记录了一次在CDH5.14.0集群上使用MapReduce处理历史数据时遇到的内存溢出问题。任务在运行过程中,由于物理内存和虚拟内存超出限制,导致YARN容器被杀死。分析表明,问题源于内存设置不足和数据分布不明。解决方案包括调整mapreduce.map.memory.mb和mapreduce.reduce.memory.mb的大小,增大yarn.nodemanager.vmem-pmem-ratio,以及优化程序以减少内存使用。最终,通过命令行参数设置增大内存配置解决了问题。此案例强调了生产环境中数据分布了解的重要性以及测试环境与生产环境的差异可能带来的挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

小菜鸟的个人博客已经正式上线且对外开放啦…

博客访问地址小菜鸟的大梦想

欢迎各位同学扫码关注本人公众号 ↓↓↓ 更多优质内容将 首发 公众号
在这里插入图片描述



背景

较早之前项目组一次新需求上线时,需要初始化Hive中某张表的全量历史数据。该表由于历史原因导致ETL处理的时候,2015年前的数据产出文件(定长压缩文件)时为同一个ETL日期,也就是这张表的分区日期,由于涵盖多年的数据,并且数据文件较大又分为多个日期,数据存放Hive时需要按照其真实业务日期进行重分区。线上集群同时有部分Spark任务存在,所以决定采用Mapreduce方式进行解析入库并重分区到正式表(其中集群为CDH5.14.0)。


错误日志

由于日常开发测试与生产环境物理隔离,日志无法获取,以下日志来源于网络)

......
18/05/15 09:36:59 INFO mapreduce.Job: Running job: job_1525923400969_0023
18/05/15 09:37:11 INFO mapreduce.Job: Job job_1525923400969_0023 running in uber mode : false
18/05/15 09:37:11 INFO mapreduce.Job:  map 0% reduce 0%
18/05/15 09:38:15 INFO mapreduce.Job: Task Id : attempt_1525923400969_0023_m_000000_0, Status : FAILED
Container [pid=27842,containerID=container_1525923400969_0023_01_000002] is running beyond physical memory limits. Current usage: 1.0 GB of 1 GB physical memory used; 2.8 GB of 2.1 GB virtual memory used. Killing container.
Dump of the process-tree for container_1525923400969_0023_01_000002 :
    |- PID PPID PGRPID SESSID CMD_NAME USER_MODE_TIME(MILLIS) SYSTEM_TIME(MILLIS) VMEM_USAGE(BYTES) RSSMEM_USAGE(PAGES) FULL_CMD_LINE
    |- 28027 27842 27842 27842 (java) 10464 706 2861776896 266585 /usr/java/jdk1.8.0_111/bin/java -Djava.net.preferIPv4Stack=true -Dhadoop.metrics.log.level=WARN -Djava.net.preferIPv4Stack=true -Xmx820m -Djava.io.tmpdir=/home/yarn/nm/usercache/root/appcache/application_1525923400969_0023/container_1525923400969_0023_01_000002/tmp -Dlog4j.configuration=container-log4j.properties -Dyarn.app.container.log.dir=/yarn/container-logs/application_1525923400969_0023/container_1525923400969_0023_01_000002 -Dyarn.app.container.log.filesize=0 -Dhadoop.root.logger=INFO,CLA -Dhadoop.root.logfile=syslog org.apache.hadoop.mapred.YarnChild 10.3.1.9 59062 attempt_1525923400969_0023_m_000000_0 2 
    |- 27842 27839 27842 27842 (bash) 3 3 115859456 361 /bin/bash -c /usr/java/jdk1.8.0_111/bin/java -Djava.net.preferIPv4Stack=true -Dhadoop.metrics.log.level=WARN  -Djava.net.preferIPv4Stack=true -Xmx820m -Djava.io.tmpdir=/home/yarn/nm/usercache/root/appcache/application_1525923400969_0023/container_1525923400969_0023_01_000002/tmp -Dlog4j.configuration=container-log4j.properties -Dyarn.app.container.log.dir=/yarn/container-logs/application_1525923400969_0023/container_1525923400969_0023_01_000002 -Dyarn.app.container.log.filesize=0 -Dhadoop.root.logger=INFO,CLA -Dhadoop.root.logfile=syslog org.apache.hadoop.mapred.YarnChild 10.3.1.9 59062 attempt_1525923400969_0023_m_000000_0 2 1>/yarn/container-logs/application_1525923400969_0023/container_1525923400969_0023_01_000002/stdout 2>/yarn/container-logs/application_1525923400969_0023/container_1525923400969_0023_01_000002/stderr  

Container killed on request. Exit code is 143
Container exited with a non-zero exit code 143

18/05/15 09:39:21 INFO mapreduce.Job: Task Id : attempt_1525923400969_0023_m_000000_1, Status : FAILED
Container [pid=32561,containerID=container_1525923400969_0023_01_000003] is running beyond physical memory limits. Current usage: 1.0 GB of 1 GB physical memory used; 2.8 GB of 2.1 GB virtual memory used. Killing container.
Dump of the process-tree for container_1525923400969_0023_01_000003 :
    |- PID PPID PGRPID SESSID CMD_NAME USER_MODE_TIME(MILLIS) SYSTEM_TIME(MILLIS) VMEM_USAGE(BYTES) RSSMEM_USAGE(PAGES) FULL_CMD_LINE
    |- 32561 32559 32561 32561 (bash) 3 2 115859456 361 /bin/bash -c /usr/java/jdk1.8.0_111/bin/java -Djava.net.preferIPv4Stack=true -Dhadoop.metrics.log.level=WARN  -Djava.net.preferIPv4Stack=true -Xmx820m -Djava.io.tmpdir=/home/yarn/nm/usercache/root/appcache/application_1525923400969_0023/container_1525923400969_0023_01_000003/tmp -Dlog4j.configuration=container-log4j.properties -Dyarn.app.container.log.dir=/yarn/container-logs/application_1525923400969_0023/container_1525923400969_0023_01_000003 -Dyarn.app.container.log.filesize=0 -Dhadoop.root.logger=INFO,CLA -Dhadoop.root.logfile=syslog org.apache.hadoop.mapred.YarnChild 10.3.1.9 59062 attempt_1525923400969_0023_m_000000_1 3 1>/yarn/container-logs/application_1525923400969_0023/container_1525923400969_0023_01_000003/stdout 2>/yarn/container-logs/application_1525923400969_0023/container_1525923400969_0023_01_000003/stderr  
    |- 32746 32561 32561 32561 (java) 10706 764 2856566784 270760 /usr/java/jdk1.8.0_111/bin/java -Djava.net.preferIPv4Stack=true -Dhadoop.metrics.log.level=WARN -Djava.net.preferIPv4Stack=true -Xmx820m -Djava.io.tmpdir=/home/yarn/nm/usercache/root/appcache/application_1525923400969_0023/container_1525923400969_0023_01_000003/tmp -Dlog4j.configuration=container-log4j.properties -Dyarn.app.container.log.dir=/yarn/container-logs/application_1525923400969_0023/container_1525923400969_0023_01_000003 -Dyarn.app.container.log.filesize=0 -Dhadoop.root.logger=INFO,CLA -Dhadoop.root.logfile=syslog org.apache.hadoop.mapred.YarnChild 10.3.1.9 59062 attempt_1525923400969_0023_m_000000_1 3 

Container killed on request. Exit code is 143
Container exited with a non-zero exit code 143

18/05/15 09:40:30 INFO mapreduce.Job: Task Id : attempt_1525923400969_0023_m_000000_2, Status : FAILED
Container [pid=89668,containerID=container_1525923400969_0023_01_000004] is running beyond physical memory limits. Current usage: 1.0 GB of 1 GB physical memory used; 2.8 GB of 2.1 GB virtual memory used. Killing container.
Dump of the process-tree for container_1525923400969_0023_01_000004 :
    |- PID PPID PGRPID SESSID CMD_NAME USER_MODE_TIME(MILLIS) SYSTEM_TIME(MILLIS) VMEM_USAGE(BYTES) RSSMEM_USAGE(PAGES) FULL_CMD_LINE
    |- 89966 89668 89668 89668 (java) 10823 859 2856423424 267248 /usr/java/jdk1.8.0_111/bin/java -Djava.net.preferIPv4Stack=true -Dhadoop.metrics.log.level=WARN -Djava.net.preferIPv4Stack=true -Xmx820m -Djava.io.tmpdir=/home/yarn/nm/usercache/root/appcache/application_1525923400969_0023/container_1525923400969_0023_01_000004/tmp -Dlog4j.configuration=container-log4j.properties -Dyarn.app.container.log.dir=/yarn/container-logs/application_1525923400969_0023/container_1525923400969_0023_01_000004 -Dyarn.app.container.log.filesize=0 -Dhadoop.root.logger=INFO,CLA -Dhadoop.root.logfile=syslog org.apache.hadoop.mapred.YarnChild 10.3.1.9 59062 attempt_1525923400969_0023_m_000000_2 4 
    |- 89668 89666 89668 89668 (bash) 3 3 115859456 361 /bin/bash -c /usr/java/jdk1.8.0_111/bin/java -Djava.net.preferIPv4Stack=true -Dhadoop.metrics.log.level=WARN  -Djava.net.preferIPv4Stack=true -Xmx820m -Djava.io.tmpdir=/home/yarn/nm/usercache/root/appcache/application_1525923400969_0023/container_1525923400969_0023_01_000004/tmp -Dlog4j.configuration=container-log4j.properties -Dyarn.app.container.log.dir=/yarn/container-logs/application_1525923400969_0023/container_1525923400969_0023_01_000004 -Dyarn.app.container.log.filesize=0 -Dhadoop.root.logger=INFO,CLA -Dhadoop.root.logfile=syslog org.apache.hadoop.mapred.YarnChild 10.3.1.9 59062 attempt_1525923400969_0023_m_000000_2 4 1>/yarn/container-logs/application_1525923400969_0023/container_1525923400969_0023_01_000004/stdout 2>/yarn/container-logs/application_1525923400969_0023/container_1525923400969_0023_01_000004/stderr  

Container killed on request. Exit code is 143
Container exited with a non-zero exit code 143

任务运行现象:查看YARN历史任务监控,发现该MR任务运行的时间较长,但随后报错导致任务失败。


异常分析

重点关注日志:

Container [pid=27842,containerID=container_1525923400969_0023_01_000002] is running beyond physical memory limits. 
Current usage: 1.0 GB of 1 GB physical memory used; 2.8 GB of 2.1 GB virtual memory used. Killing container.

以上日志信息很明显的提示内存溢出了。

Container is running beyond physical memory

这个问题出现主要是因为物理内存不足导致的,在执行mapreduce的时候,每个map和reduce都有自己分配到内存的最大值,当map函数需要的内存大于这个值就会报这个错误。

running beyond virtual memory limits. Current usage: 1.0 GB of 1 GB physical memory used; 2.8 GB of 2.1 GB virtual memory used. Killing container.

该错误是YARN的虚拟内存计算方式导致,上例中用户程序申请的内存为1Gb,YARN根据此值乘以一个比例(默认为2.1)得出申请的虚拟内存的值,当YARN计算的用户程序所需虚拟内存值大于计算出来的值时,就会报出以上错误。

这里注意几个内存值大小:1.0G,1G,2.8G,2.1G,分别代表:

1.0GB:任务所占的物理内存
1GB: mapreduce.map.memory.mb 参数默认设置大小
2.8GB:程序占用的虚拟内存
2.1GB: mapreduce.map.memory.mb 乘以 yarn.nodemanager.vmem-pmem-ratio

其中 yarn.nodemanager.vmem-pmem-ratio 是虚拟内存和物理内存比例,在yarn-site.xml中设置,默认是2.1。
很明显,container占用了2.8G的虚拟内存,但是分配给container的却只有2.1GB,所以kill掉了这个container。

上面只是map中产生的报错,当然也有可能在reduce中报错,如果是reduce中,那么就是mapreduce.reduce.memory.db * yarn.nodemanager.vmem-pmem-ratio。

注:

物理内存:内存条
虚拟内存:利用磁盘空间虚拟划出的一块逻辑内存,用作虚拟内存的磁盘空间被称为交换空间(Swap Space)。(为了满足物理内存的不足而提出的策略)
linux会在物理内存不足时,使用交换分区的虚拟内存。内核会将暂时不用的内存块信息写到交换空间,这样以来,物理内存得到了释放,这块内存就可以用于其它目的,当需要用到原始的内容时,这些信息会被重新从交换空间读入物理内存。


解决办法

1. 如果集群数量多,增加map或者reduce的个数,均衡一下

2. 取消虚拟内存的检查(不建议)
在yarn-site.xml或者程序中中设置yarn.nodemanager.vmem-check-enabled为false

# 物理内存检查
<property>
  <name>yarn.nodemanager.pmem-check-enabled </name>
  <value>false</value>
  <description>Whether physical memory limits will be enforced for containers.</description>
</property>
# 虚拟内存检查
<property>
  <name>yarn.nodemanager.vmem-check-enabled</name>
  <value>false</value>
  <description>Whether virtual memory limits will be enforced for containers.</description>
</property>

除了虚拟内存超了,也有可能是物理内存超了,同样也可以设置物理内存的检查为 yarn.nodemanager.pmem-check-enabled :false
个人认为这种办法并不太好,如果程序有内存泄漏等问题,取消这个检查,可能会导致集群崩溃。

3. 增大mapreduce.map.memory.mb 或者 mapreduce.reduce.memory.mb(建议)

个人觉得是一个办法,应该优先考虑这种办法,这种办法不仅仅可以解决虚拟内存,或许大多时候都是物理内存不够了,这个办法正好适用。

4. 适当增大 yarn.nodemanager.vmem-pmem-ratio的大小

为物理内存增大对应的虚拟内存, 但是这个参数也不能太离谱

除了以上这些,还需要考虑程序是否可以再优化一下,尽量少创建新对象,以及数据本身是否存在数据倾斜等,优先从程序方面解决此类问题。

最终采用方式:
本次操作主要为大量历史数据的初始化操作,平日线上集群跑批并未出现过此类问题,所以最终决定通过命令行参数的方式进行设置,在执行重分区操作之前 额外 添加以下参数:

set mapreduce.map.memory.mb=10240;	#设置map内存大小
set mapreduce.reduce.memory.mb=10240;	#设置reduce内存大小

总结

本次生产异常的原因主要有以下几个方面:
1. 生产环境与开发测试完全隔离,也就是开发测试过程中完全无法接触任何生产环境的数据;
2. 实际数据的分布情况不明确,仅从相关业务部门得知到很少一部分信息;
3. 测试环境没有大量的数据提供测试,并且以上两个 memory 参数已经设置为8GB,已经不算小了;
4. 同一时刻生产环境还有其它离线及实时任务在运行(这个是事先就需要考虑到的)。

生产环境此表的数据完全黑盒,数量大概在8亿左右,也无法事先得知各业务日期下数据的分布情况,而此次操作是从 文件转换压缩格式到HDFS目录 --> 定长解析HDFS目录文件到Hive临时表 --> 按照业务日期重分区到Hive正式表 一系列流程依次执行的(一开始就未采用分步执行的方式),然而第三阶段就出现了内存问题。

另外呢,负责我们项目组的运维同事大多时候也是太SB(死板),感觉都是把我们研发往死里搞的,有几次让帮忙查询服务日志都不给查,谁让人家运维是公司大佬部门。

反正最后就还是归为自己考虑不周的原因,明知道数据黑盒,还“一鼓作气”。其实,搞我们这一行的吧,谁还不是秉着“一切从简、从优”的原则干的。

以上就瞎吐槽着玩玩,各位大佬不喜 勿喷!勿喷!

<think>好的,我现在需要解决用户遇到的Hive错误:[08S01][2] Error while processing statement: FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask。首先,我要理解这个错误的背景和可能的原因。 首先,这个错误发生在执行Hive查询时,特别是当Hive将任务提交到MapReduce引擎时出现了问题。返回码2通常表示MapReduce任务执行失败。接下来,我需要考虑可能导致MapReduce任务失败的常见原因。 可能的原因有很多,我需要逐一分析: 1. **资源问题**:集群资源不足,比如内存或CPU不够,导致任务无法分配足够的资源而失败。这时候需要检查YARN的资源管理,查看是否有足够的内存和vcores可用。可能需要调整mapreduce.map.memory.mb、mapreduce.reduce.memory.mb等参数。 2. **数据倾斜**:在数据处理过程中,某个reduce任务处理的数据量远大于其他任务,导致该任务超时或内存溢出。用户需要检查数据分布,是否存在某个key的数据异常多的情况,可能需要优化SQL,比如添加随机前缀进行分散。 3. **磁盘空间不足**:如果HDFS或本地磁盘空间不足,任务可能无法写入中间结果。需要检查集群的磁盘使用情况,清理不必要的文件或扩展存储空间。 4. **代码错误**:HiveQL语句可能存在语法错误或逻辑错误,比如字段名错误、表不存在等。需要仔细检查用户的HiveQL语句,尤其是最近修改的部分。 5. **配置问题**:Hive或Hadoop的配置参数不正确,比如mapred.reduce.tasks设置不合理,或者Hivehive.execution.engine设置错误(比如应该使用Tez却用了MR)。需要检查相关配置文件,如hive-site.xml和mapred-site.xml。 6. **依赖缺失**:任务中引用了外部资源(如UDF、jar包)但路径不正确或权限不足。需要确认ADD JAR或ADD FILE的路径是否正确,以及用户是否有访问权限。 7. **日志分析**:查看具体的MapReduce任务日志,尤其是失败任务的stderr和syslog,可以更准确地定位问题。用户可以通过YARN的ResourceManager Web UI找到应用ID,然后查看对应日志。 8. **权限问题**:执行任务的用户没有访问相关HDFS目录或表的权限,导致任务失败。需要检查HDFS目录的权限设置,使用hadoop fs -ls命令查看,并使用chmod或chown调整。 接下来,我需要给用户一个结构清晰的解决方案,分步骤指导他们排查问题。可能需要建议他们按照常见原因逐一检查,比如先看日志,确认错误详情,再检查资源、数据倾斜等。同时,提醒用户如何调整配置参数,优化查询语句,处理数据倾斜的方法,以及如何检查权限和磁盘空间。 另外,用户可能需要具体的命令示例,比如如何查看YARN应用日志,如何调整内存参数,如何处理数据倾斜的SQL改写示例。这些都需要在回答中给出,帮助用户实际操作。 最后,需要强调系统级指令中的格式要求,确保数学表达式和独立公式正确使用LaTeX,保持回答的中文,结构清晰,分点说明可能原因和解决步骤,并确保所有技术细节准确无误。</think>该错误提示表明Hive在执行MapReduce任务时遇到问题(常见于Hive on MR模式)。以下是分步排查和解决方案: --- ### 一、核心错误定位 错误码 `return code 2` 表示MapReduce作业失败,需通过以下命令获取详细日志: ```bash # 获取YARN应用ID(替换application_123456789_0001) yarn logs -applicationId application_123456789_0001 > hive_error.log ``` 重点关注日志中的 `Caused by:` 部分。 --- ### 二、常见原因及解决方案 #### 1. 内存不足(最常见) **现象**:日志中出现 `Container killed by YARN for exceeding memory limits` **解决方案**: 调整Hive内存参数(单位:MB): ```sql SET mapreduce.map.memory.mb=4096; -- 默认值通常为1024 SET mapreduce.reduce.memory.mb=8192; SET mapreduce.map.java.opts=-Xmx3072m; -- 通常设为0.8*map内存 SET mapreduce.reduce.java.opts=-Xmx6144m; ``` #### 2. 数据倾斜 **现象**:某个Reduce任务处理数据量异常大 **优化方法**: ```sql -- 原始写法 SELECT key, COUNT(*) FROM table GROUP BY key; -- 优化写法(添加随机前缀打散) SELECT split_key, COUNT(*) FROM ( SELECT key, CONCAT(key, '_', CAST(RAND()*10 AS INT)) AS split_key FROM table ) tmp GROUP BY split_key; ``` #### 3. 磁盘空间不足 **检查命令**: ```bash hdfs dfs -df -h /user/hive/warehouse # 检查HDFS空间 df -h # 检查本地磁盘空间 ``` #### 4. 权限问题 **验证命令**: ```bash hadoop fs -ls /user/hive/warehouse/mytable # 检查目录权限 hadoop fs -chmod -R 755 /path/to/dir # 修改权限(示例) ``` #### 5. 配置错误 检查关键配置项: ```xml <!-- hive-site.xml --> <property> <name>hive.execution.engine</name> <value>tez</value> <!-- 建议切换至Tez引擎 --> </property> <!-- mapred-site.xml --> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> ``` --- ### 三、高级调试技巧 1. **最小化复现**:用 `LIMIT 100` 缩小数据集测试 2. **EXPLAIN分析**: ```sql EXPLAIN EXTENDED SELECT ... FROM ... WHERE ...; ``` 3. **强制本地模式**(小数据集适用): ```sql SET hive.exec.mode.local.auto=true; ``` --- ### 四、典型错误日志对照表 | 日志关键词 | 解决方案 | |---------------------------|--------------------------------------| | GC Overhead limit exceeded | 增加内存或优化数据倾斜 | | FileNotFoundException | 检查表路径/分区是否存在 | | Permission denied | 调整HDFS权限或Kerberos认证 | | Container running beyond physical memory limits | 调大 `mapreduce.*.memory.mb` | 建议优先检查YARN队列资源使用情况(通过ResourceManager Web UI),再结合具体错误日志定位问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值