数据倾斜的表现与代价
数据倾斜指某些分区键对应的数据量或流量远大于其他分区:表现为个别分片或实例的 CPU、磁盘与延迟明显偏高,批处理任务出现长尾(大部分任务早早完成,少数任务拖到最后)。代价是整体资源按最热分片配置,成本上升而利用率不高,同时热点分片的过载会直接变成超时与失败。治理手段有三类:换更均匀的分布键、对确认的热点键加盐拆分、以及为热点单独建立处理路径。
基本信息
| 识别 | 对比各分片行数、吞吐与延迟分布,找明显偏差 |
|---|---|
| 加盐 | 热点键追加随机后缀分散写入,读取时聚合 |
| 重选 | 改用分布更均匀且仍贴合查询的分片键 |
| 局限 | 加盐会增加读取与统计的复杂度,只对确认的热点键使用 |
典型使用场景
- 分库分表路由:按用户或商户分片时出现少数超大租户
- 批处理与聚合计算:单个键的数据量超出单任务处理能力,任务长尾
- 消息分区:某个业务键的消息量远超其他键,单个消费者被打满
- 缓存分片:热点键集中到少数节点,节点负载不均
- 指标统计:按维度聚合时高基数维度造成倾斜
加盐拆分示意
加盐拆分示意
原键:user_id=42 → shard = 42 % 16 → 单分片热点
加盐:key = '42#' + rand(0..3) → 写入分散到 4 个分片
读取:并发读 4 个盐值分片后合并
统计:按原始 user_id 聚合,忽略后缀
注意:只对确认的热点键加盐,避免全量加盐倾斜类型与对策
| 类型 | 特征 | 对策 |
|---|---|---|
| 键分布不均 | 少数键数据量远大于其他键 | 更换分片键或引入二级散列 |
| 单键热点 | 某个键的访问量远超其他键 | 加盐拆分写入,读取时并发合并 |
| 空值或默认值键 | 大量记录落到同一个分片 | 为缺失值分配独立分片或改写默认键 |
| 阶段性倾斜 | 大促或批量任务期间集中到少数分片 | 临时扩大并发或提前拆分热点任务 |
治理步骤
- 识别:按分片统计行数、QPS 与延迟分布,找明显离群分片
- 分类:键分布不均、单键热点与空值键,治理手段各不相同
- 改造:先对确认的热点键加盐或改写路由,避免全量重构
- 验证:治理后用同一统计口径复测,确认分片间差异收敛
- 监控:把分片间差异做成常态指标,避免改造后再次失衡
倾斜治理要同时验证查询模式:加盐拆分后按原键查询需要合并多份数据,如果读取路径无法并发合并,查询延迟反而会上升。
用哈希取模分片时扩容会改变键到分片的映射:需要一致性哈希或预分配分片方案,否则一次扩容就触发全量数据迁移,倾斜治理的成果也会被打乱。