问题描述
EMR集群的HDFS HA不可用,停掉header1 NameNode,header2无法变成active,导致两个header都处于down。
分析过程
1. 使用top、free -h等命令查看主机内存使用情况,发现内存使用正常。HDFS进程占有率较高,达到6.7%。
2. 查看HDFS、NameNode GC日志。从HDFS日志看到有报错:java.lang.OutOfMemoryError: Java heap space,并且异常前频繁Full GC,并伴随concurrent mode failure(并发失败)的错误。
3. 初步判断由于NameNode在垃圾回收时频繁concurrent mode failure 退化为Full GC,最终垃圾回收速度小于垃圾产生速度最终触发OOM,而原因往往和GC参数、堆内存、业务频繁读写HDFS相关
4. 调整参数 XX:CMSInitiatingOccupancyFraction 为60,调大堆内存到8G后启动NameNode成功,服务恢复。
方案结论
1. NameNode JVM参数可在hadoop-env下 hadoop_namenode_opts 配置项查看
列举部分参数:
- -Xms4096m:启动时堆内存大小,4G
- -Xmx8192m:运行过程中分配的最大内存,8G
- -XX:ParallelGCThreads=8:垃圾回收线程并行度
- -XX:+UseConcMarkSweepGC :使用CMS垃圾回收器
- -XX:CMSInitiatingOccupancyFraction=60:当老年代堆内存达到60%时开始进行CMS GC
2. 调整参数的意义
① -Xms
NameNode存储元数据(文件名、创建时间、大小、权限、文件与block块映射关系) ,随着用户集群业务的增大,如果NameNode无法启动请适当调大启动堆内存大小,避免出现NameNode启动读取fsimage镜像文件时间过长或者初始堆内存不够大导致启动失败。
② -XX:CMSInitiatingOccupancyFraction
NameNode启动后,若频繁Full GC,可以考虑调小CMSInitiatingOccupancyFraction的值,即更早的进行CMS GC。另外由于CMS是一款并发垃圾回收器,即用户线程和GC线程在并发标记、并发清理阶段是同时进行,所以需要预留内存空间给用户线程使用,否则容易出现concurrent mode failure导致full gc。如果要解决concurrent mode failure的问题,通常会从三个方面考虑:
- 适当调大堆内存空间-Xmx
- 适当调低CMSInitiatingOccupancyFraction的值(不建议调整的过小,容易导致更频繁的CMS GC)
- 控制对象创建频率(一般用户自己的application可以通过此方面入手进行优化,这里由于是系统进程,最多控制业务层面的读写操作,不适用)
适用范围
开源大数据平台E-MapReduce