环境准备
根据官方文档的描述, 需要先下载 ShardingSphere-Proxy 的发行版, 配置代理并运行, 然后由我们的 idea 直连 ShardingSphere-Proxy 这个代理数据库.
我采用下载发行版的方式 (比较推荐, 参数错误可以在日志中检查), 部署步骤如下:
- 下载发行版
- 解压并配置各个配置项: conf 文件夹下的 service.yaml 与各种 config-xxx.yaml
- 启动 bin/start.sh (自定义端口只需紧跟命令后面即可) , 并查看 logs/stdout.log 日志是否启动失败
读写分离
读写分离的配置文件是 conf 文件夹下的 config-readwrite-splitting.yaml
将 ShardingSphere 5.0.0-beta 版下的 example 示例拷贝过来稍作更改即可, 具体路径为:
examples/shardingsphere-proxy-example/shardingsphere-proxy-boot-mybatis-example/src/main/resources/conf/config-readwrite-splittiong.yaml
在程序中根据 yaml 文件配置, mysql 的链接路径替换成 ShardingSphere-Proxy 的 (3316是启动时自定义的端口):
jdbc:mysql://127.0.0.1:3316/readwrite-splitting_db
程序中编写了两个 RestfullApi 方法, 分别是插入数据与读取. 实际调用的效果如下:
- 调用插入数据的方法, 并紧接着执行读取 SQL, 得到的结果是: 数据写入 write_ds 库, 但是读取的数据来自 read_ds_0 读库 (这点和直接使用 ShardingSphere-JDBC 有区别, 暂时没研究)
- 多次调用读取方法, 会轮询读取多个从库
分库分表
依旧是将官方示例中的分库分表相关配置文件拷贝到 conf 文件夹下, 具体路径是:
examples/shardingsphere-proxy-example/shardingsphere-proxy-boot-mybatis-example/src/main/resources/conf/config-sharding.yaml
这里将 sharding_db
作为 Proxy 代理的数据库, 代理 demo_ds_0
、demo_ds_1
两个真实库.
schemaName: sharding_db ## 代理逻辑库
dataSources:
ds_0:
url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false ## 真实库ds_0
username: root
password: 123
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
maintenanceIntervalMilliseconds: 30000
ds_1:
url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false ## 真实库ds_1
username: root
password: 123
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
maintenanceIntervalMilliseconds: 30000
rules:
- !SHARDING
tables:
t_order: ## 分表逻辑名
actualDataNodes: ds_${0..1}.t_order_${0..1}
tableStrategy:
standard:
shardingColumn: order_id ## 分表依赖字段
shardingAlgorithmName: t_order_inline ## 分表算法
keyGenerateStrategy:
column: order_id
keyGeneratorName: snowflake ## 键生成方式
t_order_item:
actualDataNodes: ds_${0..1}.t_order_item_${0..1}
tableStrategy:
standard:
shardingColumn: order_id
shardingAlgorithmName: t_order_item_inline
keyGenerateStrategy:
column: order_item_id
keyGeneratorName: snowflake
bindingTables: ## 绑定表
- t_order,t_order_item
broadcastTables: ## 广播表
- t_address
defaultDatabaseStrategy: ## 分库策略
standard:
shardingColumn: user_id ## 分库依赖字段
shardingAlgorithmName: database_inline ## 分库算法
defaultTableStrategy:
none:
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}
t_order_item_inline:
type: INLINE
props:
algorithm-expression: t_order_item_${order_id % 2}
keyGenerators:
snowflake:
type: SNOWFLAKE
props:
worker-id: 123
根据这个配置, 在使用官方示例时, 能正确展示执行情况:
在 user_id 不同时, 数据库的选择也会根据算法进行分片
这里发现分表情况一直相同, 可以看到分表的 order_id 字段是由雪花算法生成, 而这个值一直是偶数, 这也是导致没有走到另一个表的原因.
加密
在分表的雪花算法这折腾太久, 这块先放着…
小结
ShardingSphere-Proxy 提供了透明化的数据库代理服务端, 使用它进行读写分离与分库分表时, 仅需直连代理端的逻辑库进行操作, 底层的数据分片与读写分离规则, 都通过配置文件自动处理好, 非常方便.
当然这个的局限性还是在于部署上, 后续准备继续学习它的云原生时代的产物 ShardingSphere-Sidecar