本系列的原码对应:ShardingSphere-5.0.0-beta
1、说明
本次将会通过examples里面提供的测试用例开始shardingsphere的学习。
2、添加examples项目
examples项目默认未被maven加载,通过idea右边maven +号,把examples目录导进来
3、初始化数据库
3.1、初始化示例数据库
在examples/src/resources目录下,我们可以看到一个manual_schema.sql的文件,执行该数据库脚本后,即可完成示例数据库的初始化
我的环境是vm中的docker mysql5.7,直接通过Navicat Premium连接上数据库,执行该脚本,这部分没有要求,我用的是mysql数据库,shardingsphere jdbc目前支持 MySQL,Oracle,SQLServer,PostgreSQL 以及任何遵循 SQL92 标准的数据库。
3.2、修改连接信息
要想运行demo需要先修改jdbc的配置,分为DataSourceUtil类和yaml配置两种,自行选择
在examples->shardingsphere-jdbc-example->sharding-example->sharding-raw-jdbc-example下
修改examples->example-core->example-api中的DataSourceUtil类
修改resources->sharding-databases.yaml文件,其余文件一样,用到哪个修改哪个
4、ShardingSphere jdbc 功能测试
根据测试类进入OrderServeiceImpl类中,进行断点观看运行情况,对processSuccess方法进行断点跟踪
ps:断点的意义在于,测试用例会删除数据,不通过断点无法清晰的看到运行效果
4.1、分库示例
代码默认即为分库
private static ShardingType shardingType = ShardingType.SHARDING_DATABASES;
复制代码
分库规则
rules:
- !SHARDING
tables:
t_order:
actualDataNodes: ds_${0..1}.t_order
keyGenerateStrategy:
column: order_id
keyGeneratorName: snowflake
t_order_item:
actualDataNodes: ds_${0..1}.t_order_item
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}
keyGenerators:
snowflake:
type: SNOWFLAKE
props:
worker-id: 123
props:
sql-show: false
复制代码
从ds_${user_id % 2};这句配置可以看到,是按user_id对2取模来确定放到哪个库。
4.2、分表示例
使用分表
private static ShardingType shardingType = ShardingType.SHARDING_TABLES;
复制代码
分表规则
rules:
- !SHARDING
tables:
t_order:
actualDataNodes: ds.t_order_${0..1}
tableStrategy:
standard:
shardingColumn: order_id
shardingAlgorithmName: t_order_inline
keyGenerateStrategy:
column: order_id
keyGeneratorName: snowflake
t_order_item:
actualDataNodes: ds.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
shardingAlgorithms:
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
props:
sql-show: false
复制代码
可以看到t_order和t_order_item表分别模2的规则进行数据分表
发现分表失败,数据并未按id取模,经过分析发现取模规则是order_id,改为对user_id字段取模即可
修改sharding-tables.yaml:
shardingColumn: user_id
algorithm-expression: t_order_${user_id % 2}
复制代码
4.3、分库分表示例
使用分库分表
private static ShardingType shardingType = ShardingType.SHARDING_DATABASES_AND_TABLES;
复制代码
分库分表规则
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
props:
sql-show: false
复制代码
可以看到, 默认分库算法是对user_id按2取模;分表算法也都是按各自的id按2取模,就是简单的路由下。
和分表一样存在配置上的问题,改动如下:
rules:
- !SHARDING
tables:
t_order:
actualDataNodes: ds_${0..1}.t_order_${0..3}
tableStrategy:
standard:
shardingColumn: user_id
shardingAlgorithmName: t_order_inline
keyGenerateStrategy:
column: order_id
keyGeneratorName: snowflake
t_order_item:
actualDataNodes: ds_${0..1}.t_order_item_${0..3}
tableStrategy:
standard:
shardingColumn: user_id
shardingAlgorithmName: t_order_item_inline
keyGenerateStrategy:
column: order_item_id
keyGeneratorName: snowflake
bindingTables:
- t_order,t_order_item
defaultDatabaseStrategy:
standard:
shardingColumn: user_id
shardingAlgorithmName: database_inline
defaultTableStrategy:
standard:
shardingColumn: user_id
shardingAlgorithmName: t_order_inline
shardingAlgorithms:
database_inline:
type: INLINE
props:
algorithm-expression: ds_${user_id % 2}
t_order_inline:
type: INLINE
props:
algorithm-expression: t_order_${user_id % 2}
t_order_item_inline:
type: INLINE
props:
algorithm-expression: t_order_item_${user_id % 2}
复制代码
存在的问题是每个库都冗余出了2张表,还是没能达到预期,后面尝试使用address_id进行分表,使用user_id进行分库,会出错大致意思应该是不支持同时使用2个字段进行路由。这边猜测应该是我对分库分表理解不到位。
Exception in thread "main" org.apache.shardingsphere.infra.exception.ShardingSphereException: Insert statement does not support sharding table routing to multiple data nodes.
复制代码
4.4、读写分离示例
使用读写分离
private static ShardingType shardingType = ShardingType.READWRITE_SPLITTING;
复制代码
我的测试环境:通过docker模拟2台mysql服务器,设置主从同步
1、master 192.168.10.135:3310 (docker1)
2、salve 192.168.10.135:3311 (docker2)
复制代码
读写分离规则
dataSources:
write_ds:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.jdbc.Driver
jdbcUrl: jdbc:mysql://192.168.10.135:3310/demo_write_ds?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
read_ds_0:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.jdbc.Driver
jdbcUrl: jdbc:mysql://192.168.10.135:3311/demo_write_ds?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
rules:
- !READWRITE_SPLITTING
dataSources:
pr_ds:
writeDataSourceName: write_ds
readDataSourceNames: [read_ds_0]
props:
sql-show: false
复制代码
为了验证读写分离,我将slave数据库中同步到的数据进行删除,发现printData();打印出来的数据的确是slave中的,至此读写分离测试完成
4.5、加密示例
在examples->shardingsphere-jdbc-example->other-feature-example->encrypt-example->encrypt-raw-jdbc-example下
老套路断点UserServiceImpl类中processSuccess方法
记得修改数据库连接 encrypt-databases.yaml
加密规则:
rules:
- !ENCRYPT
tables:
t_user:
columns:
user_name:
plainColumn: user_name_plain
cipherColumn: user_name
encryptorName: name_encryptor
pwd:
cipherColumn: pwd
assistedQueryColumn: assisted_query_pwd
encryptorName: pwd_encryptor
encryptors:
name_encryptor:
type: AES
props:
aes-key-value: 123456abc
pwd_encryptor:
type: assistedTest
复制代码
3.6、rule 规则说明
tables: #数据分片规则配置,可配置多个logic_table_name(比如:t_order)
t_order: #逻辑表名
actualDataNodes: ds_${0..1}.t_order #真实数据节点(数据库中真实表名)
keyGenerateStrategy: #主键生成策略
column: order_id #主键名
keyGeneratorName: snowflake
bindingTables: #绑定表,即分片规则一致的关系表,互为绑定表关系。绑定表之间的多表关联
查询不会出现笛卡尔积关联,可以提升关联查询效率。
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}
复制代码
总结
本次主要是通过对examples模块中的sharding jdbc的运行,来寻找突破口了解和学习shardingsphere原码。测试了jdbc模块的分库、分表、读写分离、密码加密等功能,demo中还有jpa和mybatis版,也是对上诉功能的测试用例,其原理大同小异,并未深入探究。本次主要是对rules的yaml配置进行了深入学习,通过修改掌握了配置参数的设置,并发现inline的配置方式既简洁又高效。
近期评论