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,我只看三个指标:
- Compaction 队列长度:如果长时间大于 100,说明积压严重。
- Compaction 耗时:单次 Major Compaction 超过 1 小时,就要考虑调整参数了。
- 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 存储层监控的核心维度串起来了。你可以把它贴在工位上,排查问题时对着看。
4.7 实战:一条告警引发的排查
最后分享一个真实案例。某天凌晨 2 点,告警系统弹出:HBase 集群写入延迟 P99 超过 2 秒。我当时的排查路径是这样的:
- 先看 RegionServer 状态:发现一台 RegionServer 的 RPC 队列长度到了 3000,其他节点正常。初步判断是热点问题。
- 再看 Compaction 队列:那台 RegionServer 的 Compaction 队列长度 150,IO 占比 60%。嗯,问题找到了——Compaction 把 IO 吃光了。
- 查磁盘水位:HDFS 使用率 82%,不算高。但 WAL 目录所在磁盘使用率 91%,接近保护模式阈值。
- 最终结论:WAL 目录磁盘快满了,导致 HBase 写入变慢,RegionServer 的 RPC 请求积压,Compaction 又抢 IO,恶性循环。
处理方式:临时把 WAL 目录迁移到另一块磁盘,同时停掉 Major Compaction。15 分钟后延迟恢复正常。第二天重新规划了磁盘分配,给 WAL 目录单独留了 500GB 空间。
我的建议:存储层监控一定要做「关联分析」。单一指标告警往往找不到根因,把读写延迟、Compaction、磁盘水位放在一张 dashboard 里,一眼就能看出问题链条。