单库数据量过亿后,索引深度、写入锁竞争、备份时间都会恶化。分库分表是把数据按分片键拆到多个库表,分散读写压力。ShardingSphere是Java生态接入成本较低的分库分表方案之一,本文给出分片策略选型、配置实例与存量数据平滑迁移方法。
分片键与分片策略的选择
分片键决定路由是否均匀。订单类场景优先用用户ID,既保证同一用户订单落在同一分片,又让查询能被路由裁剪。ShardingSphere内置几种常用分片算法:
- 取模分片 hash-mod:user_id % 8,实现简单,但扩容要翻倍增加分片,迁移量大;
- 一致性哈希 hash:扩容只需迁移部分数据,适合读多写少;
- 时间分片 interval:按月份切表,适合日志流水,冷热分离明显;
- 复合分片:多个分片键组合,覆盖多维度查询。
rules:
- !SHARDING
tables:
t_order:
actualDataNodes: ds_$0-1.t_order_$0-3
tableStrategy:
standard:
shardingColumn: user_id
shardingAlgorithmName: user_hash_mod
keyGenerateStrategy:
column: id
keyGeneratorName: snowflake
shardingAlgorithms:
user_hash_mod:
type: HASH_MOD
props:
sharding-count: 8
取模分片对扩容不友好,设计时要预留扩容空间(比如一次分64表),避免中途改分片数量。
分片键限制与绑定表、广播表配置
分片后跨节点join不可行,关联查询要避免。为此ShardingSphere提供绑定表,让订单表与订单明细表按同一分片键落到同一物理节点,join可在节点内完成:
bindingTables:
- t_order,t_order_item
字典表、配置表等数据量小且不分片的表配置为广播表,每个库都放一份完整数据,避免跨库关联。
平滑迁移:双写校验与灰度切流
存量数据迁移到分片环境,直接切换风险大。标准流程分三步:
- 双写阶段:应用层同步写旧库与ShardingSphere新库,事务以旧库为准,新库失败仅告警;
- 数据回填:用ETL工具回填历史数据,按分片键统计新旧库行数并抽样比对,不一致自动重放;
- 灰度切流:新库读流量先放10%用户,确认无差异后逐步放开,最终停写旧库。
# 双写期对账脚本核心思路
for key in select_distinct_user_ids():
old_cnt = query_old(f"SELECT COUNT(*) FROM t_order WHERE user_id={key}")
new_cnt = query_new(f"SELECT COUNT(*) FROM t_order_{key % 8} WHERE user_id={key}")
assert old_cnt == new_cnt, f"user {key} diff"
分片后的常见坑与兜底方案
分库后需要全局唯一的字段(如手机号)无法依赖数据库唯一索引,改为业务层唯一键生成或引入分布式ID;跨库查询用Elasticsearch或ClickHouse做聚合;每个分片上的慢查询要用explain逐个排查。分片是重要架构决策,选型前评估未来三年数据量增长与查询模式,避免先分后合的返工成本。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/fen-ku-fen-biao-shi-zhan-shardingsphere-fen-pian-ce-lyue-yu/