7.3 常见故障排查:从症状到根因 本节摘要:故障排查的难点不在"不知道命令",而在"从模糊症状到具体根因的收敛路径"。本节把四类高发故障(写入变慢、读取抖动、RegionServer 宕机、ZooKeeper 异常)整理成决策树,每一支给出对应的日志特征、确认命令与处置动作,最后补上权限与安全这条常被忽略的故障来源。 先分类,再动手 值班时收到"HBase 有问题",第一件事是逼问出症状类别。四类高发故障的入口判断: 写入变慢:put/批量任务耗时上升、客户端超时增多; 读取抖动:点查或扫描 P99 抬升、偶发慢查询; 节点宕机:某台 RegionServer 掉线、Master 日志刷恢复流程; 元数据异常:连不上集群、表状态卡死、ZooKeeper 会话告警。
本节摘要:故障排查的难点不在"不知道命令",而在"从模糊症状到具体根因的收敛路径"。本节把四类高发故障(写入变慢、读取抖动、RegionServer 宕机、ZooKeeper 异常)整理成决策树,每一支给出对应的日志特征、确认命令与处置动作,最后补上权限与安全这条常被忽略的故障来源。
值班时收到"HBase 有问题",第一件事是逼问出症状类别。四类高发故障的入口判断:
四类往下钻的路径完全不同,图 7.3-1 给出全景。用这张图的方式不是从头读到尾,而是从最像的那个症状出发,沿着分支逐个确认——每一步的确认手段都是 7.1 节讲过的指标或命令。

写入路径的每一环都有队列(2 章的主线),排查就是看哪个队列先堆积。
第一步看 RegionServer 的 Flush 队列与 MemStore 水位。如果 Flush 队列持续大于 10、MemStore 总内存逼近上限,说明落盘速度跟不上写入速度——IO 层瓶颈。日志里能找到对应证据:
WARN regionserver.HRegion: MemStore is above high water mark ... WARN regionserver.MemStoreFlusher: Exceeded max blocking size ... blocked for 18422 ms
"blocked for 18422 ms" 是最直白的自白:写入被阻塞了 18 秒。这一支的处置按 7.1 节的对照表:错峰 Compaction、给 Compaction 限流、必要加盘。
第二步如果队列正常,看单 Region 的写入量分布。用 7.1 节的 list_region 确认是否热点:某个 Region 的请求量独大,就是行键没打散(5.1 节的老朋友)。处置分两步走——先 move 应急,再排 RowKey 改造。特别提醒:热点 Region 所在机器经常连锁出现 Flush 频繁、Compaction 排队,让第一眼的诊断偏向 IO 问题;先看请求分布再看队列,能少走弯路。
第三步排除法查客户端侧:批量任务是否突增、是否有大 Value 写入(单值几十 MB 会把 Flush 与 Compaction 全拖慢)。RPC 队列堆积但服务端各队列都空,问题大概率在客户端连接与并发配置(4.3 节)。
读路径的问题多数能归到三件事:缓存被冲刷、StoreFile 碎片化、布隆缺失。
典型日志特征是 BlockCache 命中率从九成掉到五成。追问一句"那时候谁在跑"——十个案例里八个是某个大扫描任务把缓存全冲了(6.2 节讲过 LRU 逐出)。处置:大扫描改用扫描旁路(不进缓存的读)或错峰执行。
碎片化的证据是 StoreFile 数量曲线缓慢爬升、点查延迟同步抬升。确认后手动触发一次合并能立竿见影,但根治要调 Compaction 触发阈值(3.2 节)。布隆缺失最容易确认:describe 一眼可见,列族属性里 BLOOMFILTER 是 NONE 而访问模式又是随机点查,补上 ROW 即可。
还有一类伪装成读取抖动的问题其实是 GC:点查延迟尖刺与 GC 日志里的长停顿时刻吻合。这类问题的解法不在读路径,回到 7.1 节的 JVM 调优——把缓存挪堆外、压停顿目标。
节点宕机的处置原则是先定死因,再谈重启。Master 日志会给出完整时间线:
INFO master.RegionStates: Transition {d6f1...} {OPENING -> CLOSED} on vm3 ... INFO wal.WALSplitter: Split wal group ...:102470937 bytes in 9213 ms INFO master.AssignmentManager: ... assigned to vm2
三行分别对应:Region 下线、WAL 切分(九秒切完一百 MB 日志)、Region 落到新宿主。恢复慢不慢,看切分与重分配各占多少——切分慢说明日志积压多(写入猛),重分配慢多半是打开 Region 时回放久。
死因排查看宕机机的最后日志:OOM 前通常有一串堆告警;磁盘满会刷 write failed;长 GC 则有停顿记录。没定死因就重启,最常见的结局是十分钟后再挂一次——尤其 OOM 类问题,重启只是清空了现场。
顺带一个容量经验:单台 RegionServer 上的 Region 数超过三四百,宕机恢复的重分配风暴会明显拉长,客户端抖动加剧。这与 7.1 节"单机 Region 上限"的红线呼应——Region 数既是性能问题也是恢复问题。
连接突然全部报错、表操作卡死,先查 ZooKeeper。四字命令最快:
$ echo ruok | nc zk1 2181 imok $ echo stat | nc zk1 2181 | head -4 Zookeeper version: 3.7.1-- Clients: 84 Latency min/avg/max: 0/2/41
重点看两处:Clients 数是否异常暴涨(客户端连接泄漏会把连接数顶到上限,后续连接全部被拒);Latency max 是否飙高(ZooKeeper 自身磁盘抖动,会话心跳跟不上)。另一个高频根因藏在 HBase 侧:RegionServer 长 GC 停顿超过会话超时,ZooKeeper 判定其死亡并广播,但进程其实活着——这就是"脑裂前兆",表现为明明进程在却看到它掉线的告警。解法还是治 GC,或适当调大会话超时(代价是真宕机时判定变慢,要权衡)。
最后一类故障不报错在日志里,而表现为"有的连接好有的不好":权限配置问题。HBase 的 ACL 在 Shell 里按命名空间、表、列族、列四级授权:
hbase:120:0> grant 'etl_user', 'RW', 'orders' hbase:121:0> user_permission 'orders' User Table Family Qualifier Permissions etl_user orders - - [Read, Write]
生产集群至少做三件事:关掉匿名访问(Kerberos 或至少认证开关)、按系统分账号授权(ETL 与线上服务分列)、Meta 与系统表权限收紧。安全问题的排查特征是"症状跟着来源 IP 或账号走",与机器无关——这与前面四类按机器分布的故障正好互补,遇到"换台机器就好"的问题时,往权限上想。
⚠️ 常见坑:把排查工具本身变成故障源。全表 count、大范围 scan 在生产高峰跑,本身就能制造一次读写抖动,然后你会在自己制造的抖动里排查半天。任何诊断扫描先设 LIMIT 与时间范围,低峰执行。
机制、调优、排障都齐了。下一节用两个完整案例收束全册:时序数据与用户画像,把前面所有章节的决策放进真实需求里再走一遍。