第六章:分区
1. 分区的目标
分区(Partition/Sharding)通过把大数据集拆到多节点,实现容量与吞吐的横向扩展。复制解决“可用性”,分区解决“规模化”,两者通常组合使用。
2. 键值分区策略
2.1 范围分区(Key Range)
按连续键区间分配分区,天然支持范围查询,但容易出现时间戳写入等热点。
2.2 哈希分区(Hash)
按哈希值打散键,负载更均匀,但范围查询通常需要 scatter/gather,查询代价上升。
2.3 复合键折中
常见做法是 (partition_key, clustering_key):
- 前缀键决定分区,保证均衡。
- 后缀键在分区内排序,保留局部范围查询能力。
2.4 热点治理
单个热点键无法靠哈希自然消除。可对热点键加随机后缀分裂写入,读取时再聚合,但会提升读路径复杂度。
3. 分区与二级索引
3.1 本地索引(Local Index)
每个分区仅维护本地索引,写入成本低。缺点是按二级条件查询时需要广播到全分区。
3.2 全局索引(Global Index)
索引本身也分区,按索引项直达目标分区,读性能更好。代价是写入需要跨分区更新,常依赖异步维护并接受短暂不一致。
4. 再平衡(Rebalancing)
4.1 目标约束
- 负载均衡。
- 迁移期间持续可读写。
- 数据迁移量最小化。
4.2 常见策略
4.2.1 避免 hash(key) mod N
节点数变化会导致大量键重映射,引发全量迁移风暴。
4.2.2 固定分区数
预先创建较多分区,扩容时迁移分区归属,适合运维可控场景。
4.2.3 动态分裂合并
分区超阈值自动分裂,低负载时合并,适合数据规模持续变化场景。
4.2.4 按节点比例分区
每节点维护近似固定数量分区,扩缩容时保持管理开销稳定。
5. 请求路由
5.1 路由模式
- 任意节点接入后转发。
- 独立路由层代理。
- 客户端持有分区元数据直连。
5.2 元数据一致性
分区映射可由 ZooKeeper/etcd 等协调服务维护,也可走 gossip 协议最终收敛。
5.3 并行查询执行
跨分区查询通常采用并行 fan-out,再在协调节点聚合结果。此时要重点关注:
- 最慢分区拖尾(尾延迟放大)。
- 去重与排序的内存压力。
- 分页一致性语义。
6. 设计建议
- 若范围查询是核心需求,优先范围分区并配合热点治理。
- 若写入均衡优先,采用哈希分区并接受范围查询代价。
- 再平衡策略应先于上线确定,避免扩容期重构成本。