6.2 监控与性能调优 本节摘要:监控体系按"存储层、资源层、节点层"三个观察面组织,各层有五六个核心指标即可覆盖九成故障。调优按"四查"流程定位瓶颈再动参数。本节给出指标清单、告警阈值经验值、四查定位法与最常用的参数调优对照表。 三个观察面,各守一段旅程 监控的常见失败是指标太多、信号太少。有效做法是按前五章的架构分层设观察哨:存储层看 NameNode(账本与块健康)、资源层看 ResourceManager(容器与队列)、节点层看 NodeManager 与 DataNode(单机水位)。
本节摘要:监控体系按"存储层、资源层、节点层"三个观察面组织,各层有五六个核心指标即可覆盖九成故障。调优按"四查"流程定位瓶颈再动参数。本节给出指标清单、告警阈值经验值、四查定位法与最常用的参数调优对照表。
监控的常见失败是指标太多、信号太少。有效做法是按前五章的架构分层设观察哨:存储层看 NameNode(账本与块健康)、资源层看 ResourceManager(容器与队列)、节点层看 NodeManager 与 DataNode(单机水位)。每个观察面抓核心指标:
| 观察面 | 指标 | 健康区间经验值 | 越界含义 |
|---|---|---|---|
| NameNode | RPC 队列延迟 | <10ms | 主控过载或客户端风暴 |
| NameNode | 堆内存使用 | <75% | 账本膨胀(小文件)或泄漏 |
| NameNode | 丢块数 Missing Blocks | 0 | 立即告警,最高优先级 |
| NameNode | 下线副本 UnderReplicated | <1000 | 节点故障或副本风暴 |
| RM | 可用容器数 | 稳定水位 | 集群空闲或配置未生效 |
| RM | 待分配容器 Pending | 无长期积压 | 队列满或调度瓶颈 |
| RM | AppMaster 失败率 | <1% | AM 内存不足或队列 AM 份额满 |
| NodeManager | 容器内存超限杀死数 | 偶发 | 任务内存配置系统性偏小 |
| DataNode | Xceiver 线程数 | <80%上限 | 读写请求堆积 |
| DataNode | 磁盘利用率 | 80%告警 | 需要均衡(2.4 节) |
指标不在多而在"每个指标都对应一个你知道怎么处置的故障"——收集了却没人知道越界后该做什么的指标,只是仪表盘上的装饰品。建议每季度做一次指标大扫除:把半年内从未触发、或触发后无人行动的条目移出告警列表,保持信号的信噪比,这是监控体系长期不腐化的关键。采集通道:Hadoop 各守护进程内置 JMX 指标,可对接 Prometheus 加 Grafana 仪表盘(开源栈标准组合),或用管理平台自带监控(Ambari Alerts)。关键不在工具而在告警分级:丢块、NN 不可达属"电话叫醒"级;副本下线超阈值、队列积压属"工作时间处理"级;磁盘 80%、堆内存爬升属"周会讨论"级。

多数团队把监控当消防器——响了再处理。更有价值的用法是当雨量计:把每周的核心指标存下来做趋势,就得到容量规划的输入。三个趋势最有预测力。一是 NameNode 堆内存的周斜率:线性外推即可知道几个月后触顶,提前启动小文件治理或联邦评估(2.4 节),而不是在告警当周手忙脚乱。二是各队列容量利用率的分位数:如果 etl 队列连续一个月 P95 利用率超过九成,扩容或调额的申请就有了数据背书,比"感觉慢"的口头报告有力得多。三是磁盘利用率的离散度:节点间差距持续拉大说明写入热点或 Balancer 缺位,两周一次的例行均衡该安排了。监控数据的第二生命周期(趋势与容量)往往比第一生命周期(告警)更能体现平台团队的专业度——毕竟告警响应救的是今天,趋势分析救的是下个季度,而容量规划做得好的团队,甚至能让绝大多数告警根本没有机会响起来。
慢作业排障最常见的错误是上来就调参数。正确顺序是四查,每查有明确的证据来源:
一查 CPU:任务容器 vCore 利用率打满(YARN 页面任务明细可见),且多数时间在用户态——真计算密集,加核或优化代码;在系统态——多半是序列化或 GC,先查压缩编解码与 Writable 选择。
二查内存:3.3 节的 Spilled records 与 Map output 比值异常、容器被杀计数上升。前者加大 io.sort.mb 或上 Combiner,后者上调 mapreduce.map/reduce.memory.mb——注意同时调大 JVM 子选项(-Xmx 通常设为容器内存的 0.8)。
三查 IO:DataNode 磁盘 util 接近 100%、队列深度高。证据在节点级监控。读写混合场景下,小文件风暴(Flume 滚动配置错、Hive 分区过碎)是头号嫌疑人,回到 5.4 与 5.1 的治理手段。
四查网络:作业的 shuffle bytes 时间曲线与网卡水位对照。跨机架流量占比高时,检查副本放置与本地性命中率(作业计数器里有本地/跨架任务数),必要时确认机架映射正确。
四查的共同纪律:每次只改一个变量,改前改后用同一作业压测对比,并把每次改动的参数、依据、效果记录在案,逐年沉淀成团队自己的调优台账。调优事故多数源于"一口气改五个参数,快了不知为何快,慢了不知为何慢"。
用一个真实形态的案例把四查串起来。症状:夜批里 Hive 聚合作业近期从四十分钟涨到三小时,无代码改动。一查 CPU:容器 vCore 利用率仅三成,排除算力不足。二查内存:作业计数器里 Spilled records 是 Map output 的六倍——缓冲反复溢写,实锤之一;同时发现容器被杀数为零,说明不是任务内存不足。三查 IO:DataNode 磁盘 util 高位震荡,与溢写写盘的时间线吻合,实锤之二。四查网络:shuffle bytes 曲线正常,排除网络。结论收敛为"中间结果暴涨导致溢写放大",继续追因:查上游数据质量,发现新接入的埋点字段把行宽从 200 字节撑到 2 KB,而查询实际只用到三列——切换表存储为 ORC 列存并开启中间压缩后,作业回到五十分钟。这个案例的教训有普遍性:性能问题常常不在计算层,而在数据的形态层;四查定位到现象,最终解药往往在 5.1 节(列存)或 5.4 节(摄入质量)。
| 参数 | 默认 | 何时调 | 方向 |
|---|---|---|---|
| mapreduce.task.io.sort.mb | 100MB | Spilled 比值高 | 调大至任务内存一半 |
| mapreduce.map.memory.mb | 1GB | 容器被杀 | 按数据行宽调大 |
| yarn.nodemanager.resource.memory-mb | 8GB | 新机器上线 | 设为物理内存减系统与DN预留 |
| yarn.scheduler.minimum/maximum-allocation-mb | 1/8GB | 小任务碎片 | minimum 调小提利用率 |
| dfs.namenode.handler.count | 10 | RPC 队列延迟高 | 约为节点数的3% 上限200 |
| dfs.datanode.handler.count | 10 | 读延迟高 | 适度上调 |
注意 yarn.nodemanager.resource.memory-mb 这一项是新手集群"只跑得动几个任务"的最常见原因——默认 8GB,256GB 的机器只交出 8GB 给容器。上线时按物理内存减去系统、DataNode、RegionServer 预留重新设定。
观测与调优就位后,下一节补上最后一块木板:安全。