分库分表实战:ShardingSphere分片策略与平滑迁移方案

单库数据量过亿后,索引深度、写入锁竞争、备份时间都会恶化。分库分表是把数据按分片键拆到多个库表,分散读写压力。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

字典表、配置表等数据量小且不分片的表配置为广播表,每个库都放一份完整数据,避免跨库关联。

平滑迁移:双写校验与灰度切流

存量数据迁移到分片环境,直接切换风险大。标准流程分三步:

  1. 双写阶段:应用层同步写旧库与ShardingSphere新库,事务以旧库为准,新库失败仅告警;
  2. 数据回填:用ETL工具回填历史数据,按分片键统计新旧库行数并抽样比对,不一致自动重放;
  3. 灰度切流:新库读流量先放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/

(0)
小编小编
上一篇 1小时前
下一篇 1小时前

相关推荐