分布式存储热点分区如何治理?
简化版
热点分区是某个 shard 的 QPS、字节、CPU 或锁竞争远高于其他分片,集群总体有余量也无法分摊。治理先区分容量热点、读热点、写热点和单 key 热点,再选择迁移分片、增加只读副本、缓存、拆分 range、key 加盐或业务聚合;仅加机器但不改变路由通常无效。
详细版
检测不能只看节点平均值,要下钻到 shard/key:每分片 QPS、带宽、P99、队列、CPU、锁等待、leader 所在节点和 top key。
读热点可增加 follower read、缓存或复制热点对象;写热点不能简单多副本并行写,因为仍需统一顺序,可拆 key/range、按时间桶分散或先聚合再批量写。
若一个租户占 40% 写量,tenant_id 作为分片键会把流量集中。改成 tenant_id + bucket 的 16 桶可把写分散,但查询需 fan-out,且强事务范围扩大。
迁移只适合“分片热、节点不均”;单 key 无论把分片搬到哪里仍是热点。治理动作要限速、可回滚,并避免热点在节点间来回漂移。
完整版教学
一、先区分四种热点
容量热点表示数据字节偏大;读热点是重复查询集中;写热点是更新吞吐集中;单 key 热点还可能造成行锁或串行共识瓶颈。四者表现都可能是 P99 升高,但手段不同,误判会把问题搬家而非解决。
| 类型 | 典型信号 | 首选方向 |
|---|---|---|
| 容量热点 | shard bytes 高 | 拆分与迁移 |
| 读热点 | read QPS 高 | 缓存、读副本 |
| 写热点 | leader/write 高 | 改分片键、聚合 |
| 单 key 热点 | 锁等待、单 key 占比高 | 拆 key 或业务串行化 |
二、为什么集群平均值会骗人
10 台节点平均 CPU 30%,其中一台热点 Leader 可能已 95%。集群级指标看似充足,请求却排队超时。必须同时查看节点、分片、租户和 key 四个维度,并把热点与路由元数据关联。
hot_score = max(qps/p_qps, bytes/p_bytes, cpu/p_cpu, latency/p_latency)
阈值应结合持续时间,避免一次大查询触发频繁迁移。可要求连续 5 分钟超过集群中位数 3 倍且 P99 超 SLO,再进入治理队列。
三、分片迁移适合什么情况
若热点由多个普通 key 组成,且节点上同时放了多个热分片,把其中一个 Leader 或副本迁走可以均衡资源。迁移前要看目标节点、机架、磁盘水位和已有 Leader,迁移中限制快照带宽。
单 key 占据 80% 流量时,迁移只能换一台机器承压。系统应先用 top-key 证据判断热点粒度,再决定调度还是改模型。
四、读热点治理
不可变或允许陈旧的数据可以用 CDN、本地缓存、请求合并和多读副本。强一致读则要考虑副本应用进度和读屏障,不能为了分流直接读取落后 Follower。
例如热点配置每秒读 50 万次、每分钟更新一次,本地缓存 1 秒可把后端压力大幅下降;但权限撤销类数据可能不能容忍 1 秒旧值,需要版本推送或强校验。
五、写热点治理
写入必须有单一顺序时,增加副本反而增加复制成本。可把可交换计数拆成 16 个桶,写入按请求哈希分散,读取再汇总;也可在内存聚合 100 次增量后批量落盘。
这些方案改变语义:分桶让实时总值需要 fan-out,批量聚合扩大故障丢失窗口。余额、库存等带不变量的数据不能未经证明就拆成最终一致计数。
六、防止治理震荡
热点会随活动变化。自动调度要设置冷却期、收益阈值和迁移成本估算,避免刚迁完又迁回。拆分时先复制、追增量、校验后切路由;旧路由请求要重定向或带 epoch 拒绝。
监控治理前后 P99、top-key 占比、迁移字节、cache hit、fan-out、错误率和热点持续时间。若治理后总成本更高,应能一键停止或回滚。
记忆钩子:先问热点落在“节点、分片还是单 key”,再决定“搬、复制还是拆”;层级判断错了,动作越大越危险。
七、常见误区与追问
- 误区:扩容一定能解决热点。 路由不变时新增节点可能完全接不到热点流量。
- 误区:写热点增加读副本就能解决。 写仍需排序和复制,瓶颈可能更重。
- 误区:key 加盐没有代价。 查询 fan-out、事务边界和聚合复杂度都会上升。
- 追问:怎么发现单 key 热点? 采样 top key、锁等待和单 key 流量占比,并保护敏感 key。
- 追问:强一致读怎么分流? 选择已追到读水位的副本,或使用协议支持的 follower read。
- 追问:自动迁移如何防抖? 使用持续阈值、冷却期、迁移预算和收益评估。
八、加强记忆
热点治理的主线是“定位粒度—识别读写—选择手段—验证副作用”。分片不均用迁移,读热用缓存和副本,写热用拆分或聚合,单 key 则必须改变访问模型。所有自动动作都要有 epoch、限速、冷却和回滚。