微信优化

weixinyouhua

yarn内存配置怎么调?mapreduce内存参数设置详解

2026-09-03 07:42:16

配置Yarn内存的核心答案是:先明确物理机可用内存,再依次设置NodeManager总内存、Container内存上下限,最后调整应用的内存比例,三层缺一不可。

yarn 内存配置 最佳实践

很多人在配Yarn时只改一个yarn.nodemanager.resource.memory-mb,结果集群不是内存超卖就是大量Container被杀,业内专家指出,Yarn的内存管理本质是“租约制”:NodeManager向系统“租”一块内存,再切分成小份租给Container,你管不好这层租约,应用跑得再欢也白搭。

第一层:NodeManager可分配内存

配置文件是yarn-site.xml,核心参数是yarn.nodemanager.resource.memory-mb,这个值表示本节点所有Container能使用的物理内存总和,它不等于机器内存,例如一台128GB内存的服务器,要预留系统进程、OS页缓存、HDFS DataNode等约25%的内存,留下的75%才能交给Yarn。

此时别急着填96GB,还要考虑是否部署了其他服务,如果节点同时跑了HBase RegionServer或Elasticsearch,那memory-mb要再砍掉一大块,行业共识认为,单机内存超过64GB时,Yarn分配比控制在70%~80%是比较稳妥的区间。

第二层:Container内存上下限

yarn.scheduler.minimum-allocation-mb和yarn.scheduler.maximum-allocation-mb定义了每个Container的内存范围,前者默认为1GB,后者默认8GB,重点在于:maximum值决定了单个任务能申请的内存上限,如果你的Spark Executor要12GB,而maximum还是8GB,任务会直接申请失败,日志里出现“Invalid request”或内存不足信息。

建议把这两个值调整为:

  • minimum:2GB或4GB
  • maximum:等于NodeManager总内存,或者其一半(如果你希望单个任务独占一半以上内存,就设为全部)

同时确保yarn.nodemanager.vmem-check-enabled的设置符合预期,默认true,会检查虚拟内存,经常误杀容器,对于Spark或Flink跑大内存作业,可以将yarn.nodemanager.vmem-pmem-ratio调大到2.5或更大,甚至直接关闭虚拟内存检查。

第三层:分配给应用的内存比例

Yarn只管分配,不关心应用内部怎么用,但应用自己需要向Yarn申请内存,这一层最容易“内存不够”却怪Yarn配置错了。

yarn内存配置怎么调?mapreduce内存参数设置详解

例如MapReduce,mapreduce.map.memory.mb和mapreduce.reduce.memory.mb要显式设置,不要依赖默认值,因为默认Map内存是1GB,遇到大字典或复杂解析会OOM,还要调整mapreduce.map.java.opts(老版本是mapred.child.java.opts),让堆内存约占Container内存的80%,Container给了2GB,堆却只给512MB,浪费空间不说,GC也会频繁触发。

实操验证配置是否生效

修改完配置文件后,执行以下步骤验证:

  1. 首先关闭旧服务:yarn-daemon.sh stop resourcemanager 和 yarn-daemon.sh stop nodemanager(新版本用yarn --daemon stop)。
  2. 然后清空临时状态:rm -rf /tmp/hadoop-yarn/(仅测试环境用,生产环境谨慎)。
  3. 接着逐个启动ResourceManager和NodeManager。
  4. 使用yarn node -list -all查看节点状态,确认内存值显示正确。
  5. 在Web UI的“Nodes”页面,检查Vmem和Physical Memory使用率,确保没有接近100%。

yarn 内存溢出 怎么解决

当你的任务反复报Container killed by the ApplicationMaster、OutOfMemoryError或者GC overhead limit exceeded,多数组件问题出在应用自身而非Yarn,但“yarn 内存溢出 怎么解决”这个搜索词背后,大家真正想知道的是排查路径。

先看日志再调参

别一上来就加内存,第一件事是查看Container日志,在ResourceManager Web UI里找到任务,点开Attempt的日志链接,筛选stderr部分,如果是堆内存溢出,会出现java.lang.OutOfMemoryError: Java heap space;如果是堆外内存溢出,会出现Direct buffer memory或native memory相关字样。

yarn内存配置怎么调?mapreduce内存参数设置详解

症状 可能原因 优先调整项
频繁Full GC 堆太小 增大容器内存及java.opts
虚拟内存超限 vmem检查误判 关闭vmem检查或调大比例
物理内存被kill 节点总内存超卖 减少NodeManager内存
任务启动后瞬间失败 maximum小于请求值 调大scheduler maximum

调整有先后顺序:先扩堆,再扩容器

不少数据工程师直接改mapreduce.map.memory.mb翻倍,却忘记同步改java.opts,结果容器内存大了,堆还是原来那点,问题依旧,正确的顺序是:

  • 把Container大小增加到需求值的1.2~1.5倍。
  • 同步调整对应java.opts为Container大小的75%~80%。
  • 同时将yarn.app.mapreduce.am.resource.mb(ApplicationMaster内存)适当调大,避免AM先死。

别忘了检查物理机缓存

Yarn执行任务时,HDFS读缓存和网络缓冲都会占用Page Cache,如果你的/proc/meminfo里Committed_AS接近CommitLimit,说明系统有内存泄漏风险,此时需要调低NodeManager的memory-mb,给系统留出足够余量,多数情况下,12GB内存的机器,Yarn最多给8GB是安全的。

不同集群规模的内存配置建议

没有一套配置能通吃所有机器,但可以参考下面的推荐值,这里以每台机器内存为基准,不考虑CPU密集模型训练场景。

  • 48GB内存节点:NodeManager给24GB,yarn.scheduler.maximum设为8GB,单个Container上限2GB,适合小规模数据清洗。
  • 64GB内存节点:NodeManager给40GB,maximum设12GB,minimum设2GB,适合跑中等Spark作业。
  • 128GB内存节点:NodeManager给96GB,maximum设32GB,minimum设4GB,适合大容量ETL和机器学习训练。
  • 256GB内存节点:NodeManager给192GB,maximum设48GB,但要注意yarn.nodemanager.vmem-pmem-ratio必须调大或关闭检查。

如果你用的是CDH或HDP等发行版,建议在Cloudera Manager或Ambari的页面里修改,避免手改XML导致配置管理混乱,同时要记得给每个节点设置相同的yarn.scheduler.maximum-allocation-mb,否则任务在不同节点间迁移时会报错。

yarn 内存配置 对Spark任务的影响

如果你的作业是Spark On Yarn,那么spark.executor.memory、spark.executor.cores和spark.executor.memoryOverhead这三个参数需要和Yarn的maximum-allocation-mb

yarn内存配置怎么调?mapreduce内存参数设置详解

联动,常见错误是executor.memory + executor.memoryOverhead超过了Yarn允许的Container最大值,导致ApplicationMaster反复重试。

推荐计算公式:每个Executor的Spark内存申请 = spark.executor.memory + spark.executor.memoryOverhead(默认为Executor内存的10%),把这个总和与yarn.scheduler.maximum-allocation-mb比较,保证前者小于等于后者,例如你设置了2个Executor,每个分配8GB,overhead 1GB,那么Yarn的maximum至少是9GB,否则会出现“Container launch failed”或“Allocation request exceeds maximum”的提示。

Q&A:yarn 内存配置 常见问题

如何查看当前Yarn内存的实际使用情况?
在终端运行yarn node -list -all获取节点ID,再运行yarn node -status <节点ID>,输出中的Capability显示该节点可分配内存,Used Memory显示已占用,如果Used长期超过Capability的90%,说明集群内存紧张,需要降低应用并行度或增加节点。

关闭了虚拟内存检查会不会导致物理内存被过量使用?
关闭yarn.nodemanager.vmem-check-enabled只是放弃了对虚拟内存上限的监控,物理内存超限仍由操作系统内核强制回收,如果Container内存总和超过机器物理内存,会发生严重换页甚至是OOM Kill,所以关闭虚拟内存检查的前提是你已经限制了NodeManager总内存,并且应用堆外内存消耗可控,对于JVM作业,同时控制-XX:MaxDirectMemorySize可以降低风险。

同一套Yarn集群可以同时跑MapReduce和Spark吗?
可以,但需要为两类任务分别规划内存,MapReduce任务建议在配置中设置yarn.app.mapreduce.am.resource.mb和yarn.app.mapreduce.am.command-opts,Spark任务则通过Spark配置覆盖资源需求,为了防止Spark挤占MapReduce资源,可以在调度器上配置容量百分比,例如默认队列给MapReduce留30%内存,Spark队列占70%,同时使用分层队列管理。
配置内存的核心原则:先给操作系统留足余量,再给NodeManager封顶,最后让应用在Container范围内自治,按这个顺序去检查你的yarn-site.xml,大部分内存问题都能迎刃而解。

相关文章

2024年,SaaS软件行业碰到获客难、增长慢等问题吗?

我们努力让每一次邂逅总能超越期待