shardingsphere

ShardingSphere 分库分表与读写分离

补充说明

shardingsphere 是 Apache 的分布式数据库中间件,提供 ShardingSphere-JDBC(客户端 jar)和 ShardingSphere-Proxy(独立代理)两种主要接入形态。它把分库分表、读写分离、分布式事务、数据脱敏、数据加密、影子库和治理统一到一套规则配置里。

它解决单库容量、单表行数、读写压力和跨库查询问题,但不会自动消除分片带来的复杂性:跨分片 JOIN、聚合、排序、分页和事务仍需业务或中间件处理。与 MySQL Router、ProxySQL 只做连接路由不同,ShardingSphere 会解析并改写 SQL;与 Vitess 等方案相比,它更偏 Java 生态和通用数据库。选型上,JAR 模式无额外网络跳转、运维简单,但升级和语言绑定受限于应用;Proxy 模式对应用透明、支持多语言,但多一跳并需要独立部署。生产上先用 sql-show 验证路由,再逐步开启分片和读写分离。

常用示例

sh bin/start.sh
sh bin/stop.sh
mysql -h 127.0.0.1 -P 3307 -u root -p
SHOW DATABASES;
SHOW SHARDING TABLE RULES;
SHOW READWRITE SPLITTING RULES;
SHOW TRANSACTION RULES;
SHOW MASK RULES;

Proxy 默认监听 3307,DistSQL 用来查看和动态调整规则;JAR 模式用 jdbc:shardingsphere:classpath:config/shardingsphere.yaml 加载 YAML,强制路由/主库读由 HintManager 控制。

常见配置

分片规则(5.x):

dataSources:
  ds_0: {dataSourceClassName: com.zaxxer.hikari.HikariDataSource, driverClassName: com.mysql.cj.jdbc.Driver, jdbcUrl: 'jdbc:mysql://127.0.0.1:3306/app_0', username: app, password: secret}
  ds_1: {dataSourceClassName: com.zaxxer.hikari.HikariDataSource, driverClassName: com.mysql.cj.jdbc.Driver, jdbcUrl: 'jdbc:mysql://127.0.0.1:3306/app_1', username: app, password: secret}
rules:
- !SHARDING
  tables:
    t_order:
      actualDataNodes: ds_${0..1}.t_order_${0..1}
      tableStrategy: {standard: {shardingColumn: order_id, shardingAlgorithmName: t_order_inline}}
  defaultDatabaseStrategy: {standard: {shardingColumn: user_id, shardingAlgorithmName: database_inline}}
  shardingAlgorithms:
    database_inline:
      type: INLINE
      props:
        algorithm-expression: ds_${user_id % 2}
    t_order_inline:
      type: INLINE
      props:
        algorithm-expression: t_order_${order_id % 2}
props:
  sql-show: true

读写分离、脱敏与分布式事务片段:

rules:
- !READWRITE_SPLITTING
  dataSourceGroups:
    readwrite_ds: {writeDataSourceName: write_ds, readDataSourceNames: [read_ds_0], loadBalancerName: round_robin}
  loadBalancers: {round_robin: {type: ROUND_ROBIN}}
- !MASK
  tables:
    t_user:
      columns:
        phone: {maskAlgorithm: phone_mask}
  maskAlgorithms:
    phone_mask: {type: KEEP_FIRST_N_LAST_M, props: {first-n: 3, last-m: 4, replace-char: '*'}}
transaction: {defaultType: XA, providerType: Atomikos}

transaction.defaultType 取 LOCAL、XA、BASE;XA 常用 Atomikos 或 Narayana,BASE 用 Seata。不同 5.x 小版本的键名有差异:当前文档用 shardingAlgorithms、dataSourceGroups,早期版本用 algorithms、dataSources,升级时以对应版本文档为准。

易错点与排错

相关命令

读完自测

  1. 查询不带分片键时会发生什么,如何确认?
  2. 读写分离下如何保证“写后读”读到最新数据?
  3. ShardingSphere 的 LOCAL、XA、BASE 事务有什么区别?
答案
  1. 路由到所有分片广播执行,开销随分片数放大;用 sql-show 看实际 SQL 条数确认。
  2. 用 HintManager.setWriteRouteOnly() 强制走主库,或把读放在同一事务内按主库路由。
  3. LOCAL 只保证单库本地事务;XA 依赖数据库 XA 强一致但锁久;BASE 基于 Seata 补偿,最终一致。