Ubuntu Hadoop 作业优化实战指南
一 环境与健康检查
- 资源与内核
- 提升文件描述符与连接上限:提高进程可打开文件数与内核网络队列,避免“Too many open files / connection refused”。示例:
ulimit -n 65536;内核参数如 net.core.somaxconn、net.ipv4.tcp_max_syn_backlog 适度增大。
- 降低 swap 倾向:将
vm.swappiness 调低(如 10),减少内存换页导致的抖动;必要时可临时关闭 swap。
- 磁盘与文件系统:为数据盘启用 noatime 挂载,减少元数据写放大;选择适合数据密集场景的 I/O 调度器(如 deadline/noop)。
- 预读与大文件顺序读:通过
blockdev --setra 调整预读,提高顺序扫描性能。
- 监控与可视化
- 部署 Prometheus + Grafana 或 Ganglia,重点观测:HDFS 容量/剩余、DataNode 读写吞吐、NameNode RPC 延迟、YARN 队列资源使用、Container 失败与重试、Shuffle 失败与耗时。
- 快速自检命令
- 查看节点资源:
free -m、iostat -x 1、nload
- 查看 HDFS 与 YARN:
hdfs dfsadmin -report、yarn node -list -all、yarn application -list -appStates ALL
二 HDFS 与数据布局优化
- 块大小与副本因子
- 结合作业访问模式调整 dfs.blocksize(默认 128MB):大文件顺序扫描/聚合可适度增大块以减少分片与 NameNode 压力;小文件密集场景不宜过大。
- 依据可靠性与带宽权衡 dfs.replication(默认 3):跨机架/跨机房部署可保持 3,同机房高可靠网络可评估 2 以节省存储与网络。
- 小文件治理
- 合并小文件:使用 HAR、SequenceFile、或 CombineFileInputFormat 减少分片与 NameNode 内存占用。
- 开启 JVM 重用(针对大量小文件作业)可显著降低任务启动与 GC 开销。
- 存储与网络
- 优先 SSD 与多盘并行,提升 I/O 并发;为 HDFS 配置 专用网络 避免与业务流量争用。
- 启用压缩(如 Snappy/LZO)降低网络与磁盘 I/O;对冷数据做 归档 分层。
三 MapReduce Shuffle 与任务参数
- 核心 Shuffle 参数(示例为合理起步值,按内存与作业特性微调)
- 环形缓冲区:
mapreduce.task.io.sort.mb=200(默认 100MB)
- 溢写阈值:
mapreduce.map.sort.spill.percent=0.9(默认 0.8)
- 合并因子:
mapreduce.task.io.sort.factor=15(默认 10)
- Reduce 端内存缓存:
mapreduce.reduce.input.buffer.percent=0.4(默认 0.0,需确保 Reduce 堆与容器内存充足)
- 容错与推测执行
- 任务重试:在波动网络或易故障环境,将
mapreduce.{map|reduce}.maxattempts 提升到 8(默认 4)。
- 推测执行:默认开启;在“straggler”明显或存在非确定性慢节点时,可关闭或调低比例,避免资源争用与误判。
- 容器与 JVM 内存配比(示例)
- 容器内存:
mapreduce.{map|reduce}.memory.mb=2304
- JVM 堆:
-Xmx 设为容器内存的约 80%(如 2048m),为堆外与 Shuffle 预留空间
- 并发与资源:结合节点资源设置
yarn.scheduler.{min|max}-allocation-{mb|vcores} 与 yarn.nodemanager.resource.memory-mb,避免超卖。
四 作业设计与数据倾斜治理
- 输入与 Map 端
- 大量小文件:使用 CombineTextInputFormat 合并分片;在作业内尽早做 Combiner 预聚合,减少 Shuffle 数据量。
- Reduce 端
- 合理设置 mapreduce.job.reduces(不宜过少导致长尾等待,也不宜过多导致调度与资源竞争);启用 slowstart.completedmaps 让 Reduce 提前拉取数据,缩短空转时间。
- 能用 Map Join 就不用 Reduce Join;对大表分桶/排序,提升 Join 效率。
- 数据倾斜
- 抽样与范围分区:对键空间抽样,设定均衡的分区边界;必要时自定义分区器,将热点键打散到多个 Reducer。
- 预聚合与本地聚合:在 Map 端尽可能聚合,降低倾斜键的传输规模。
五 快速调优清单与验证
- 建议按“先易后难、先大后小”的顺序执行
- 合并小文件、开启压缩、使用合适 InputFormat;
- 调整 Shuffle 三件套(io.sort.mb / spill.percent / sort.factor),再视内存调高 Reduce 端 buffer;
- 结合作业特征设置合适的 Reducer 数量与 slowstart;
- 在波动环境下适度提升任务重试,必要时关闭推测执行;
- 校验容器与 JVM 配比,避免 OOM 与频繁 GC;
- 通过 Prometheus/Ganglia 观察 Shuffle 耗时、Spill/Merge 次数、Container 失败与重试、网络吞吐与丢包,按指标回滚或继续微调。
- 常用验证与观测
- 作业详情:
yarn application -status <app_id>
- 节点与队列:
yarn node -list -all、yarn queue -status <queue>
- HDFS 健康:
hdfs dfsadmin -report、hdfs fsck / -files -blocks -locations
- Web UI:NameNode 9870、ResourceManager 8088,核对数据本地性、失败与重试、Shuffle 指标。