SpringBoot3 + ShardingSphere-Proxy5.5.2 运行模式

摘要

运行模式说明

  • 运行模式

  • ShardingSphere-Proxy 运行模式分为两种:单机模式(Standalone) 和 集群模式(Cluster)。

  • 运行模式就是指定将元数据(认证、数据源、分片规则等等)持久化的存储方式。

  • 默认运行模式为单机模式,使用H2的内存方式。

单机模式(Standalone)

  • 单机模式能够将数据源和规则等元数据信息持久化,但无法将元数据同步至多个 Apache ShardingSphere 实例,无法在集群环境中相互感知。 通过某一实例更新元数据之后,会导致其他实例由于获取不到最新的元数据而产生不一致的错误。

  • 适用于工程师在本地搭建 Apache ShardingSphere 环境。

  • 单机模式目前仅支持一种:JDBC,即数据库持久化。以下为默认值(JDBCRepositoryPropertyKey)。

名称 数据类型 说明 默认值
provider String 元数据存储类型,可选值为 H2MySQLEmbeddedDerbyDerbyNetworkServerHSQLDB H2
jdbc_url String JDBC URL jdbc:h2:mem:config;DB_CLOSE_DELAY=0;DATABASE_TO_UPPER=false;MODE=MYSQL
username String 账号 sa
password String 密码 空(无默认值)
  • 这里以 Mysql 存储元数据为例,相关属性参考官网说明

1
2
3
4
5
6
7
8
9
mode:
type: Standalone
repository:
type: JDBC
props:
provider: MySQL
jdbc_url: jdbc:mysql://127.0.0.1:3306/shardingsphere?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
username: root
password: newpwd
  • 此时需要将 mysql 的驱动 jar 包 添加到 ext-lib 目录下

  • 启动 ShardingSphere Proxy 成功后会自动在上面的数据库中创建一张表,并将配置文件的中的元数据存储进去

1
2
3
4
5
6
7
CREATE TABLE `repository` (
`id` varchar(36) COLLATE utf8mb4_bin NOT NULL,
`key` text COLLATE utf8mb4_bin,
`value` text COLLATE utf8mb4_bin,
`parent` text COLLATE utf8mb4_bin,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

重点说明

  • 当数据库中不存在该表时,会自动创建该表,并将配置文件的元数据插入该表中。

  • 当数据库中已存在该表时,会读取该表中的数据并将其加载到内存,而不会读取配置文件中的元数据。即此时配置文件中的元数据不会生效。

  • 若此时想修改配置规则,有三种方法:

    • 1.删除该表,修改配置文件后重新启动Proxy,此时会重新创建该表并加载配置文件中的元数据。
    • 2.手工修改数据表中的元数据,但修改后需要重新启动Proxy才会加载新的元数据。但手工修改需要对数据的组织形式非常清楚,否则极易出错。
    • 3.[推荐]登录逻辑数据库后,使用 DistSQL 动态修改配置,修改后的配置会被保存在该表中,并立即生效,无需重启Proxy。
  • 开发和测试环境可以直接使用默认的 H2 内存数据库,生产环境可以使用 MySQL等数据库对元数据进行持久化保存或者使用下面的集群模式。

集群模式(Cluster)

  • 集群模式提供了多个 Apache ShardingSphere 实例之间的元数据共享和分布式场景下状态协调的能力。 它能够提供计算能力水平扩展和高可用等分布式系统必备的能力,集群环境需要通过独立部署的注册中心来存储元数据和协调节点状态。

  • 在生产环境建议使用集群模式。

  • 这里以 zookeeper 集群模式为例,相关属性参考官网说明

1
2
3
4
5
6
7
8
9
10
11
mode:
type: Cluster # 运行模式,默认是单机模式 Standalone
repository:
type: ZooKeeper # 注册中心类型,当前版本仅支持 ZooKeeper 和 etcd
props:
namespace: governance_ds # ZooKeeper 上的根路径(逻辑命名空间),ShardingSphere 会把所有元数据(schema 的 data_sources、rules、版本信息、运行时实例节点等)放在该 namespace 下
server-lists: localhost:2181 # ZooKeeper 集群地址列表,以逗号分隔的 host:port 列表
retryIntervalMilliseconds: 500 # 与注册中心交互失败后的重试间隔(毫秒)。网络不稳定或短暂故障时用于重试回退。
timeToLiveSeconds: 60 # 表示“临时/短期数据”的生存时间(秒),用于控制某些临时节点/实例信息的存活策略
maxRetries: 3 # 最大重试次数(超过则认为操作失败)。
operationTimeoutMilliseconds: 500 # 单次 ZooKeeper 操作(读写)的超时时间(毫秒)。

重点说明

  • 不要手工修改 Zookeeper 集群中的 namespace 下的配置信息!

  • 既然是集群,就需要多个 ShardingSphere-Proxy 实例。 当第一个 ShardingSphere-Proxy 实例 启动后,其它相同配置的 ShardingSphere-Proxy 实例仅需要一个 global.yaml 全局配置文件即可,并仅需在其中配置上面的运行模式信息,而不需要再配置其它配置,比如认证、数据源、分片规则等信息,这些信息会通过 Zookeeper 集群中的 namespace 获取并保存到本地内存中。

  • 每个 ShardingSphere-Proxy 实例启动时,都会自动将自己注册到 Zookeeper 集群中指定的 namespace 下,并自动获取该 namespace 下的配置信息。

  • 当 Zookeeper 集群中不存在指定的 namespace 时,此时第一次启动 ShardingSphere-Proxy 会自动在 Zookeeper 中创建 namespace,并写入配置文件中的配置信息到 Zookeeper 中。

  • 当 Zookeeper 集群中已存在指定的 namespace 时,此时再启动 ShardingSphere-Proxy 会自动从 Zookeeper 中读取 namespace 下的配置信息,并将其加载到内存中,不会再读取本地配置文件中的配置信息。

  • 当 Zookeeper 集群中已存在指定的 namespace 时,根据上面的规则,此时修改本地的配置文件中的分片规则后重启ShardingSphere-Proxy 并不会生效。

    • 此时有三种方法:
        1. 删除 Zookeeper 集群中指定的 namespace,然后重启 ShardingSphere-Proxy。这种方法有个弊端,即会导致连接到相同 ZooKeeper 集群的 namespace 的其它 ShardingSphere-Proxy 实例数据丢失(完全不可用),也需要重启才能重新获取到数据。
        1. 手工修改 Zookeeper 集群中指定的 namespace 下的分片规则,修改后会立即同步到所有 ShardingSphere-Proxy 实例。但手工修改需要对数据的组织形式非常清楚,否则极易出错。
        1. [推荐]登录逻辑数据库后,使用 DistSQL 动态修改配置,此时会自动同步到所有 ShardingSphere-Proxy 实例。所以,灵活掌握 DistSQL 是维护 ShardingSphere-Proxy 集群的关键。
  • 多个 ShardingSphere-Proxy 实例 可以通过负载均衡器,比如 Nginx,将请求路由到不同的 ShardingSphere-Proxy 实例。比如:

1
2
3
4
5
6
7
8
9
10
11
12
stream{
upstream shardingsphere_proxy{
server 10.10.21.35:3307;
server 10.10.21.36:3307;
}
server{
listen 3310;
proxy_connect_timeout 20s;
proxy_timeout 5m;
proxy_pass shardingsphere_proxy;
}
}

与 Spring Boot3 整合

  • 无论是 单机模式 还是 集群模式,其目的都是将 配置 保存到独立的 配置中心(数据库 或 Zookeeper)中,并让其它 ShardingSphere-Proxy 实例从该配置中心中读取配置信息。

  • 前文我们介绍过 Spring Boot3 + ShardingSphere-Proxy 就相当于是集成普通的MySql数据库,而 Spring Boot3 + ShardingSphere-JDBC 就需要单独在本地配置各种规则。

  • 实际上 ShardingSphere-JDBC 也可以从 配置中心 中读取配置信息,这样我们就不需要在本地配置任何规则了,我们仅需要在 sharding.yaml 中配置好运行模式,并配置好 databaseName 的名称即可。注意,此时配置中心的的事务不能是 XA,因为Spring Boot3 + ShardingSphere-JDBC目前不支持 XA 事务。

  • 此时,springboot项目启动后会拉取配置中心中的配置信息并将其保存到本地内存,本地配置文件中的其它配置信息会被忽略。

单机模式

  • 代码示例

  • 通过 DistSQL 改规则后,必须重启应用才能生效

  • sharding.yaml

1
2
3
4
5
6
7
8
9
10
11
mode:
type: Standalone
repository:
type: JDBC
props:
provider: MySQL
jdbc_url: jdbc:mysql://127.0.0.1:3306/shardingsphere?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
username: root
password: newpwd
# 数据库名称,默认值:logic_db
databaseName: sharding_db
  • Maven 依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!-- MySQL Connector/J -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- mybatis plus,本项目用到,非必须 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.12</version>
</dependency>
<!-- ShardingSphere JDBC 主依赖(5.5.2 建议) -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc</artifactId>
<version>5.5.2</version>
</dependency>
<!-- 自定义 的 SPI -->
<dependency>
<groupId>com.hanqf</groupId>
<artifactId>algorithm-swapper</artifactId>
<version>1.0.0</version>
</dependency>

集群模式

  • 代码示例

  • 通过 DistSQL 改规则后,立即推送到所有实例,无需重启应用。

  • sharding.yaml,注意这里一定要配置 databaseName

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# # 开启集群模式
mode:
type: Cluster # 运行模式,默认是单机模式 Standalone
repository:
type: ZooKeeper # 注册中心类型
props:
namespace: governance_ds # ZooKeeper 上的根路径(逻辑命名空间),ShardingSphere 会把所有元数据(schema 的 data_sources、rules、版本信息、运行时实例节点等)放在该 namespace 下
server-lists: localhost:2181 # ZooKeeper 集群地址列表,以逗号分隔的 host:port 列表
retryIntervalMilliseconds: 500 # 与注册中心交互失败后的重试间隔(毫秒)。网络不稳定或短暂故障时用于重试回退。
timeToLiveSeconds: 60 # 表示“临时/短期数据”的生存时间(秒),用于控制某些临时节点/实例信息的存活策略
maxRetries: 3 # 最大重试次数(超过则认为操作失败)。
operationTimeoutMilliseconds: 500 # 单次 ZooKeeper 操作(读写)的超时时间(毫秒)。
# 数据库名称,默认值:logic_db
databaseName: sharding_db
  • Maven 依赖,注意要加上 shardingsphere-cluster-mode-repository-zookeeper 的依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!-- MySQL Connector/J -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- mybatis plus,本项目用到,非必须 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.12</version>
</dependency>
<!-- ShardingSphere JDBC 主依赖(5.5.2 建议) -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc</artifactId>
<version>5.5.2</version>
</dependency>
<!-- 自定义 的 SPI -->
<dependency>
<groupId>com.hanqf</groupId>
<artifactId>algorithm-swapper</artifactId>
<version>1.0.0</version>
</dependency>
<!-- shardingsphere-cluster-mode-repository-zookeeper -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-cluster-mode-repository-zookeeper</artifactId>
<version>5.5.2</version>
</dependency>

如何选择

  • 当我使用springboot3+shardingSphere-JDBC5.5.2时,我应该使用本地配置文件的方式还是使用配置中心(比如:zookeeper)的方式呢?

方式 部署复杂度 配置动态更新 多实例共享配置 热更新支持 适用环境
本地配置文件 简单 不支持 不支持 开发/测试/小型项目
配置中心(ZooKeeper/etcd) 略高 支持 支持 生产/分布式环境
  • 注意

    • DistSQL 目前确实只支持在 ShardingSphere-Proxy 上执行,并且 Proxy 只支持 MySQL 和 PostgreSQL 协议。
    • 如果你在 Spring Boot + ShardingSphere-JDBC 里用 其它数据库(比如 SQL Server、Oracle、DB2 等),就无法直接通过 DistSQL 去动态改配置。
    • 此时你可以选择通过 Zookeeper 的客户端直接修改或配置规则,也可以不选择 配置中心 的方式,直接使用 本地配置文件

什么时候需要分库分表

  • 分库分表的主要目的是 解决数据量大带来的性能、可用性和可扩展性问题。通常需要考虑的几个关键指标:

1. 数据量指标

  • 单表数据量过大:一般来说,单表数据量在 千万级 以上时,查询、写入和索引的性能会明显下降。

  • 例如:一个订单表一天有上百万条数据,一年下来可能有上亿条,单表性能会成为瓶颈。

2. 访问量指标

  • 高并发写入或查询:数据库连接、事务锁、IO 等资源会成为瓶颈。

  • 如果你的系统每天有上千万的请求,数据库可能无法承受。

3. 业务隔离需求

  • 不同业务的数据分离,避免单个业务影响整个数据库的稳定性。

  • 例如:电商系统中的订单和日志数据,日志量非常大,和订单分开存储更合理。

4. 运营与成本因素

  • 分库分表后,可以分布到多个数据库实例上,支持 水平扩展,而不必依赖昂贵的单机数据库。

使用 ShardingSphere 可能带来的问题

  • 使用 ShardingSphere 可以方便地解决分库分表问题,但在实际生产中,它会带来一些新的复杂性和潜在问题,主要体现在性能、运维、功能限制等方面。

1. 性能与延迟

  • 跨库 JOIN 性能差
    分库分表后,跨库的 JOIN 查询会在各个分片上分别执行,然后在 ShardingSphere 层合并结果,性能明显下降。

    • 例如:订单表在多个库,查询订单 + 用户信息时必须跨库 JOIN,执行效率比单库低很多。
  • 分页查询慢
    分库分表后,如果要全局排序 + 分页,需要所有分片查出数据再合并,代价非常大。

    • 解决方式:使用分片键范围分页,或引入 ElasticSearch/ClickHouse 做搜索和统计。
  • 广播表压力
    配置了广播表(每个库一份完整数据)后,更新需要同步所有库,写入性能下降。

2. SQL 兼容性限制

  • 复杂 SQL 支持不完整
    ShardingSphere 对某些复杂 SQL(如子查询、窗口函数)支持有限,可能报错或性能极差。

  • 存储过程、触发器受限
    分库分表后,存储过程、触发器在分片数据库执行可能不一致,维护成本高。

3. 分布式事务问题

  • ShardingSphere 支持 XA 分布式事务,但性能不如单机事务,出现网络抖动时可能会卡住。

  • 如果业务需要强一致性,必须结合可靠消息或 TCC、SAGA 等分布式事务模式,架构会更复杂。

4. 运维与管理复杂度

  • 分片规则变更困难
    例如,最初按 user_id % 2 分成两个库,后续想增加到 4 个库,需要迁移数据,非常麻烦。

  • 监控与调优
    ShardingSphere 增加了中间层,SQL 路由、执行计划、数据节点状态都需要额外的监控工具支持。

5. 成本与学习曲线

  • 配置相对复杂:分片规则、读写分离、分布式事务、弹性扩容都需要仔细设计。

  • 学习曲线较陡:开发和运维人员必须了解 ShardingSphere 的工作机制,否则定位问题很困难。

6. 高可用与扩展问题

  • ShardingSphere-JDBC 是应用内库,无法独立扩展,需要依赖应用扩容。

  • ShardingSphere-Proxy 支持集群,但需要自己搭建高可用架构,涉及负载均衡、故障切换等问题。

其它技术方案:分布式数据库

  • 开源产品: 核心功能完全开源,企业版提供额外商业特性

数据库 架构类型 SQL 兼容性 分布式事务支持 数据存储模型 主要特点 典型应用场景
TiDB 分布式 HTAP MySQL 协议兼容 支持(Percolator 模型) 行存 + 列存混合 开源、云原生、强一致性、弹性扩展 在线事务处理 + 实时分析
OceanBase 分布式关系型数据库 MySQL/Oracle 兼容 支持(两阶段提交) 行存 高性能、金融级事务、阿里蚂蚁金服核心系统使用 金融、电商、核心交易系统
CockroachDB 分布式 NewSQL PostgreSQL 兼容 支持(分布式事务) 行存 类 Spanner 架构,全球分布,强一致性 全球化分布式应用
Citus (PostgreSQL) PostgreSQL 扩展 PostgreSQL 兼容 部分支持(基于逻辑分片) 行存 基于 PostgreSQL 的分布式扩展,支持大规模 OLAP 大数据实时分析、BI 场景
Vitess 分布式中间件 + 存储 MySQL 协议兼容 弱事务(最终一致性) 行存 YouTube 开源,K8s 友好,分库分表自动化 大规模 Web 应用,在线服务
YugabyteDB 分布式 SQL + NoSQL PostgreSQL 兼容 支持(两阶段提交) 行存 + 列存混合 融合 NewSQL 和 NoSQL,强一致性,跨区域部署 金融级事务 + 分析混合场景
  • 商业产品

数据库 架构类型 SQL 兼容性 分布式事务支持 数据存储模型 主要特点 典型应用场景
PolarDB 云原生分布式数据库 MySQL/PostgreSQL 兼容 支持(云端分布式事务) 行存 阿里云产品,弹性扩容,存储计算分离 云上企业数据库解决方案
GaussDB 分布式关系型数据库 MySQL/Oracle 兼容 支持(分布式事务) 行存 + 列存混合 华为推出,分布式 HTAP,云原生架构 企业级 OLTP + OLAP 混合负载
Spanner 全球分布式数据库 类 SQL 支持(TrueTime 协议) 行存 Google 云产品,全球分布式强一致事务 全球化分布式事务,金融场景
Amazon Aurora 云原生分布式关系型数据库 MySQL/PostgreSQL 兼容 支持(单实例事务,多 AZ 高可用) 行存 AWS 托管,自动扩展存储,多可用区高可用 OLTP、企业级业务