1. 增加系统物理内存
Hadoop作为分布式计算框架,对内存需求极高(尤其是NameNode、DataNode、ResourceManager等核心组件)。若频繁出现内存不足(OOM)错误,优先通过硬件升级增加Ubuntu服务器的物理内存(如从8GB扩容至16GB及以上),这是解决内存瓶颈的根本途径。
2. 调整YARN容器内存配置(YARN集群)
YARN是Hadoop的资源管理系统,负责分配容器(Container)内存。需修改yarn-site.xml文件,关键参数如下:
yarn.nodemanager.resource.memory-mb:设置每个NodeManager节点可分配的总内存(如8GB集群可设为8192MB),需小于等于节点实际物理内存;yarn.scheduler.minimum-allocation-mb:YARN分配给单个容器的最小内存(如1024MB),避免容器申请过小内存导致碎片化;yarn.scheduler.maximum-allocation-mb:YARN分配给单个容器的最大内存(如8192MB),需与yarn.nodemanager.resource.memory-mb一致或略小。sudo systemctl restart hadoop-resourcemanager hadoop-nodemanager。3. 优化MapReduce任务内存设置
MapReduce任务的JVM堆内存不足是常见问题,需调整mapred-site.xml(Hadoop 2+版本使用mapreduce前缀):
mapreduce.map.memory.mb:设置Map任务容器的内存大小(如4096MB);mapreduce.reduce.memory.mb:设置Reduce任务容器的内存大小(通常比Map任务大,如8192MB);mapreduce.map.java.opts/mapreduce.reduce.java.opts:设置Map/Reduce任务的JVM最大堆内存(需小于容器内存,建议为容器内存的70%-80%,如-Xmx3072m)。4. 调整HDFS NameNode/Datanode内存
NameNode负责元数据管理,Datanode负责数据存储,两者的内存配置需满足数据规模需求:
hdfs-site.xml中,设置dfs.namenode.memory.size(NameNode内存,如4096MB)和dfs.datanode.memory.size(Datanode内存,如2048MB);dfs.namenode.handler.count(NameNode处理请求的线程数)和dfs.datanode.handler.count(Datanode处理请求的线程数)可根据集群规模调整(如100),避免因线程过多导致内存溢出。5. 优化JVM垃圾回收(GC)
大型Hadoop任务易触发频繁Full GC,导致内存占用过高甚至进程崩溃。可通过以下方式优化:
mapred-site.xml中,为Map/Reduce任务设置GC参数,如mapreduce.map.java.opts添加-XX:+UseG1GC(使用G1垃圾回收器,适合大内存场景)和-XX:MaxGCPauseMillis=200(设置最大GC停顿时间);6. 启用数据压缩
中间数据(Map输出)和最终结果的压缩可减少内存占用和网络传输:
mapred-site.xml中,设置mapreduce.map.output.compress为true(启用Map输出压缩)和mapreduce.output.fileoutputformat.compress为true(启用最终输出压缩);snappy,压缩速度快,适合Hadoop场景),通过mapreduce.map.output.compress.codec(Map输出压缩编解码器)和mapreduce.output.fileoutputformat.compress.codec(最终输出压缩编解码器)设置(如org.apache.hadoop.io.compress.SnappyCodec)。7. 调整HDFS块大小
增大HDFS块大小可减少Map任务数量(每个块对应一个Map任务),从而降低内存开销:
hdfs-site.xml中,修改dfs.blocksize参数(单位:字节),如设置为268435456(256MB,默认128MB)。需根据数据访问模式调整(如大文件适合大块,小文件适合小块)。8. 监控与持续优化
使用监控工具(如Ganglia、Ambari、Cloudera Manager)实时跟踪集群内存使用情况(如NodeManager内存占用、Map/Reduce任务内存消耗),识别内存瓶颈(如某个节点内存使用率长期超过80%)。根据监控数据定期调整配置(如增加内存不足节点的资源分配),确保集群稳定运行。