4. HBase/ClickHouse 存储层监控:读写延迟、RegionServer 状态、Compaction、磁盘水位

存储层是实时数仓的命门。HBase 和 ClickHouse 虽然都号称能扛海量数据,但它们的脾气完全不同。HBase 依赖 RegionServer 的稳定,ClickHouse 则对 MergeTree 的合并节奏极其敏感。这一章,我把这两兄弟的监控要点掰开揉碎了讲。

核心原则:存储层监控不是看一堆数字,而是看「趋势」和「异常偏离」。值往往骗人,斜率才是真相。

4.1 HBase 读写延迟:别被平均 latency 骗了

HBase 的读写延迟,我习惯分三个维度看:P99、P999、平均。平均延迟低,不代表系统健康。有一次我在项目里看到平均延迟只有 5ms,但业务方一直在报超时。查了半天,发现是 RegionServer 的 GC 导致 P999 飙到了 3 秒。

监控指标主要有这几个:

指标名 含义 告警阈值(参考)
append_avg_time 写入平均延迟 > 50ms 预警,> 200ms 告警
read_avg_time 读取平均延迟 > 100ms 预警,> 500ms 告警
sync_avg_time HLog 同步延迟 > 200ms 告警
99th_percentile P99 延迟 > 1s 必须处理

我的习惯:把 P99 和平均延迟放在同一张图里。如果两条线突然「分叉」,说明有少量请求被卡住了。这时候别急着加机器,先查 RegionServer 的 GC 日志和 HDFS 的 RPC 延迟。

4.2 RegionServer 状态:活着不代表健康

RegionServer 的监控,很多人只看进程是否存活。这远远不够。我遇到过 RegionServer 进程在,但已经无法响应请求的情况——说白了就是「假死」。

重点看这几个状态:

  • RegionServer 的 RPC 队列长度:如果队列持续堆积超过 1000,说明处理能力到瓶颈了。
  • BlockCache 命中率:低于 85% 就要注意。命中率低,读请求会直接压到 HDFS。
  • MemStore 大小:单个 Region 的 MemStore 超过 256MB 且持续不下降,说明 flush 出了问题。
  • Compaction 队列长度:这个后面单独讲。

我曾经踩过的坑:有一次 RegionServer 的 BlockCache 命中率从 95% 掉到 60%,我以为是缓存不够,加了内存。结果发现是某张表的 rowkey 设计不合理,导致热点 Region 频繁 split。加内存治标不治本,最后重新设计了预分区才解决。

4.3 Compaction 监控:HBase 的「双刃剑」

Compaction 是 HBase 里最让人又爱又恨的机制。它能合并小文件、清理删除标记,但也会吃掉大量 IO 和 CPU。我见过因为 Compaction 把集群打挂的案例,不止一次。

监控 Compaction,我只看三个指标:

  1. Compaction 队列长度:如果长时间大于 100,说明积压严重。
  2. Compaction 耗时:单次 Major Compaction 超过 1 小时,就要考虑调整参数了。
  3. Compaction 占用的 IO 比例:超过 40% 的磁盘 IO 被 Compaction 吃掉,读写延迟必然飙升。

避坑指南:我曾经在凌晨跑定时任务做 Major Compaction,结果和业务高峰期重叠了。那天的读写延迟直接翻了三倍。后来我把 Major Compaction 改成了手动触发,只在低峰期执行。

4.4 ClickHouse 读写延迟:MergeTree 的「合并之痛」

ClickHouse 的延迟监控,核心在 MergeTree 引擎。写入延迟通常很低,但读取延迟受合并影响很大。为什么?因为合并过程中,part 文件数量会暂时增加,查询需要扫描更多文件。

关键指标:

指标名 含义 监控方式
MergeQueue 等待合并的任务数 system.metrics
ReadBackoff 读取是否被限流 system.events
InsertedRows 每秒写入行数 system.metrics
QueryTime 查询平均耗时 system.query_log

我的经验:ClickHouse 的 MergeQueue 超过 200 就要警惕。这时候查询延迟会明显上升。我一般会调大 max_part_merges_to_optimize 参数,或者临时降低写入并发,让合并线程喘口气。

4.5 磁盘水位:存储层的「最后一道防线」

磁盘满了,一切归零。HBase 和 ClickHouse 对磁盘水位的敏感度不同,但处理思路一致。

HBase 的磁盘监控要点:

  • HDFS 的 DataNode 磁盘使用率超过 85% 就要预警。
  • RegionServer 的 WAL 目录所在磁盘,必须单独监控。
  • 如果磁盘使用率超过 90%,HBase 会自动进入保护模式,拒绝写入。

ClickHouse 的磁盘监控要点:

  • MergeTree 的数据目录,磁盘使用率超过 80% 就要考虑扩容或清理。
  • 临时目录 /tmp 也要监控,排序和合并操作会写临时文件。
  • ClickHouse 没有自动保护机制,磁盘满了会直接报错。

我曾经遇到的事故:ClickHouse 集群的磁盘使用率到了 95%,我还在跑数据导入。结果 MergeTree 的合并操作因为磁盘空间不足失败,导致 part 文件越积越多,最后整个表无法查询。恢复花了整整一天。从那以后,我强制在磁盘使用率 80% 时发告警,85% 时自动停写入任务。

4.6 知识体系总览

下面这张图,把 HBase 和 ClickHouse 存储层监控的核心维度串起来了。你可以把它贴在工位上,排查问题时对着看。

存储层监控知识体系 存储层监控知识体系 HBase 监控 读写延迟 P99 / P999 / 平均延迟 / RPC 队列 RegionServer 状态 BlockCache 命中率 / MemStore / GC Compaction 队列长度 / 耗时 / IO 占比 磁盘水位 HDFS 使用率 / WAL 目录 / 保护模式 ClickHouse 监控 读写延迟 MergeTree 合并影响 / QueryTime MergeQueue 等待合并任务数 / ReadBackoff Part 文件数量 part 数过多导致查询变慢 磁盘水位 数据目录 / 临时目录 / 自动停写 核心思路:看趋势,不看值;看 P99,不看平均

4.7 实战:一条告警引发的排查

最后分享一个真实案例。某天凌晨 2 点,告警系统弹出:HBase 集群写入延迟 P99 超过 2 秒。我当时的排查路径是这样的:

  1. 先看 RegionServer 状态:发现一台 RegionServer 的 RPC 队列长度到了 3000,其他节点正常。初步判断是热点问题。
  2. 再看 Compaction 队列:那台 RegionServer 的 Compaction 队列长度 150,IO 占比 60%。嗯,问题找到了——Compaction 把 IO 吃光了。
  3. 查磁盘水位:HDFS 使用率 82%,不算高。但 WAL 目录所在磁盘使用率 91%,接近保护模式阈值。
  4. 最终结论:WAL 目录磁盘快满了,导致 HBase 写入变慢,RegionServer 的 RPC 请求积压,Compaction 又抢 IO,恶性循环。

处理方式:临时把 WAL 目录迁移到另一块磁盘,同时停掉 Major Compaction。15 分钟后延迟恢复正常。第二天重新规划了磁盘分配,给 WAL 目录单独留了 500GB 空间。

我的建议:存储层监控一定要做「关联分析」。单一指标告警往往找不到根因,把读写延迟、Compaction、磁盘水位放在一张 dashboard 里,一眼就能看出问题链条。