哈希分片与范围分片的优缺点对比
为什么需要对比
在分库分表实践中,大多数场景的纠结就是选哈希分片还是范围分片。两者各有优劣,选错了会在扩展性和查询效率上付出巨大代价。
哈希分片(Hash Sharding)
工作原理
// 核心:hash(shard_key) % shard_count
int shard = Math.abs(orderId.hashCode()) % SHARD_COUNT;
优点详解
1. 数据分布均匀
哈希函数的随机性保证了数据均匀分布到各个分片。假设有 8 个分片,每个分片大致存放 1/8 的数据,不会出现某个分片数据量是其他分片 10 倍的情况。
2. 写入负载均衡
所有分片的写入压力相当,不会出现”热点分片”——这在事务型系统(OLTP)中尤其重要。
3. 查询延迟可预测
单表数据量稳定,无论查询哪个分片,时间复杂度保持一致。
4. 充分利用集群资源
所有分片节点的资源利用率接近均等。
缺点详解
1. 范围查询需要全分片扫描
-- 查询 1 号到 1000 号用户的所有订单
-- 哈希分片下,这些订单分布在各分片
-- 需要:查询所有分片 → 归并排序 → 返回结果
SELECT * FROM order WHERE user_id BETWEEN 1 AND 1000 ORDER BY create_time;
2. 扩缩容代价巨大
// 从 8 个分片扩展到 16 个分片
// 旧路由: orderId % 8
// 新路由: orderId % 16
// 除了 0 和 8 的关系,其他数据都需要重新分布
// 约 12/16 = 75% 的数据需要迁移
3. 不支持分片键修改
如果业务修改了分片键的值,数据路由会发生错乱。
范围分片(Range Sharding)
工作原理
// 核心:按值的范围划分
if (userId <= 1_000_000) return "shard_0";
else if (userId <= 2_000_000) return "shard_1";
else if (userId <= 3_000_000) return "shard_2";
// ...
优点详解
1. 范围查询效率极高
-- 查询本周的订单,如果按时间范围分片
-- 只需要查询 1-2 个分片
SELECT * FROM order WHERE create_time BETWEEN '2024-01-01' AND '2024-01-07';
2. 扩容简单
需要扩容时,只需新增一个分片,新数据自然存入新分片,无需迁移旧数据。
user_id 1-1000万 → shard_0
user_id 1000万-2000万 → shard_1
user_id 2000万-3000万 → shard_2
...继续新增 shard_3 存后面的数据即可
3. 易于理解和管理
范围分片的路由规则直观,运维排查问题时容易查找数据位置。
缺点详解
1. 数据分布可能严重倾斜
-- 按时间分片
-- 2023 年数据 1 亿行
-- 但 2024 年才 100 万行
-- 大量查询击中旧分片,负载不均
2. 热点分片问题
最近写入的数据集中在最后一个分片,形成”尾热点”。在时间序列场景中,最后一个分片的写入压力是其他分片的数倍。
3. 跨范围查询仍有归并成本
虽然比哈希好,但当查询跨越多个范围时(如查询全量数据),仍然需要归并。
综合对比表
| 维度 | 哈希分片 | 范围分片 |
|---|---|---|
| 数据均匀性 | ✅ 优秀 | ❌ 可能有倾斜 |
| 写入均匀性 | ✅ 优秀 | ❌ 有热点分片 |
| 范围查询 | ❌ 需要广播 | ✅ 高效 |
| 等值查询 | ✅ 快速定位 | ✅ 快速定位 |
| 扩缩容 | ❌ 麻烦,大量迁移 | ✅ 简单,渐进式 |
| 实现复杂度 | 低 | 低 |
| 适用场景 | OLTP,等值查询多 | 时序数据,范围查询多 |
如何选择
优先选择哈希分片的场景
- OLTP 系统,等值查询占主导(如通过 order_id 查订单)
- 需要均匀分布写入压力的场景
- 数据量持续增长,各分片希望均衡
优先选择范围分片的场景
- 时序数据,按时间维度查询多
- 离线分析、报表等范围查询场景
- 数据冷热明显,需要按时间归档
混合方案(推荐)
大多数生产系统采用混合策略:
# 按 user_id 哈希分库,保证写入均衡
database_strategy:
algorithm: hash(user_id) % 4
# 在同一库内按月范围分表,方便时间查询
table_strategy:
algorithm: month_range(create_time)
这样既能享受哈希写入均衡的好处,又能保留范围查询的优势。
面试要点
- 两害相权取其轻:选哈希还是范围取决于业务查询模式
- 哈希分片的扩容代价常被忽视——生产环境扩缩容非常痛苦
- 数据倾斜是范围分片的最主要风险
- “二级分片”(先哈希再范围)是工程实践中常见的折中方案
- 没有完美的分片策略,理解 trade-off 比记住结论更重要
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容