简介
在上篇文章中,体验了 ShardingSphere JDBC 的数据分片、读写分离、数据加密,本篇文章就来探索下 ShardingSphere Proxy 相关的功能
示例运行
ShardingSphere Proxy 相对来说还是比较陌上的,首先肯定是官方文档了解一波:
数据分片、读写分离、数据加密的说明和配置和 ShardingSphere JDBC 一样,参考上篇文章即可
ShardingSphere JDBC 如果要接入的话,从上篇文章中可以看出,其是需要改变现有业务代码的,是侵入式的
ShardingSphere Proxy 感觉更像一个代码,只需要改变数据库的连接配置,是非侵入式的。但也增加了整个系统的复杂度,各有利弊吧
ShardingSphere Proxy 启动相关
首先找到启动的地方:shardingsphere-proxy/shardingsphere-proxy-bootstrap/src/main/java/org/apache/shardingsphere/proxy/Bootstrap.java
上面就是启动类,但还不能进行启动,需要先将 server.yaml 进行开启:shardingsphere-proxy/shardingsphere-proxy-bootstrap/src/main/resources/conf/server.yaml
下面的注释全部放开:
其中配置了 ShardingSphere 连接是用户名和密码,下面的配置文件中就配置了两个:root 和 sharding
sql-show 改为 true,看日志利于排查问题(一个示例跑起来问题真不少啊)
rules:
- !AUTHORITY
users:
- root@%:root
- sharding@:sharding
provider:
type: NATIVE
props:
max-connections-size-per-query: 1
executor-size: 16 # Infinite by default.
proxy-frontend-flush-threshold: 128 # The default value is 128.
# LOCAL: Proxy will run with LOCAL transaction.
# XA: Proxy will run with XA transaction.
# BASE: Proxy will run with B.A.S.E transaction.
proxy-transaction-type: LOCAL
xa-transaction-manager-type: Atomikos
proxy-opentracing-enabled: false
proxy-hint-enabled: false
sql-show: true
check-table-metadata-enabled: false
lock-wait-timeout-milliseconds: 50000 # The maximum time to wait for a lock
show-process-list-enabled: false
# Proxy backend query fetch size. A larger value may increase the memory usage of ShardingSphere Proxy.
# The default value is -1, which means set the minimum value for different JDBC drivers.
proxy-backend-query-fetch-size: -1
check-duplicate-table-enabled: fals
复制代码
相关的配置文件位于:shardingsphere-proxy/shardingsphere-proxy-bootstrap/src/main/resources/conf
下面有各个示例开启的配置文件,先不进行开启,跟着下面的步骤进行操作即可
使用 docker 启动一个数据库:
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:latest
复制代码
注:本地采用单个测试,所以在测试一个特性的时候,其他特性的配置文件是注释掉的
注:连接 ShardingSphere Proxy 时,数据库名称是 Proxy 的逻辑名称:schemaName,注意进行相应的修改
数据分片
1.数据库初始化
用下面的语句建立相关的数据库
CREATE SCHEMA IF NOT EXISTS demo_ds_0;
CREATE SCHEMA IF NOT EXISTS demo_ds_1;
复制代码
2.ShardingSphere Proxy 配置
放开配置:shardingsphere-proxy/shardingsphere-proxy-bootstrap/src/main/resources/conf/config-sharding.yaml
就是简单修改密码,大致配置如下:
schemaName: sharding_db
dataSources:
ds_0:
url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
ds_1:
url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
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
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
复制代码
配置完成后,重启
3.示例运行
修改配置:examples/shardingsphere-proxy-example/shardingsphere-proxy-boot-mybatis-example/src/main/resources/application.properties
让访问的数据库名和密码对上,配置大致如下:
mybatis.config-location=classpath:META-INF/mybatis-config.xml
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3307/sharding_db?useServerPrepStmts=true&cachePrepStmts=true
spring.datasource.username=root
spring.datasource.password=root
复制代码
启动后,我们就看到相关的 ShardingSphere Proxy 的日志:
Logic SQL: select @@session.transaction_read_only
SQLStatement: MySQLSelectStatement(limit=Optional.empty, lock=Optional.empty, window=Optional.empty)
Actual SQL: ds_0 ::: select @@session.transaction_read_only
Logic SQL: INSERT INTO t_order_item (order_id, user_id, status) VALUES (?, ?, ?);
SQLStatement: MySQLInsertStatement(setAssignment=Optional.empty, onDuplicateKeyColumns=Optional.empty)
Actual SQL: ds_0 ::: INSERT INTO t_order_item_0 (order_id, user_id, status, order_item_id) VALUES (?, ?, ?, ?); ::: [637039855574429696, 10, INSERT_TEST, 637039855616372737]
Logic SQL: select @@session.transaction_read_only
SQLStatement: MySQLSelectStatement(limit=Optional.empty, lock=Optional.empty, window=Optional.empty)
Actual SQL: ds_0 ::: select @@session.transaction_read_only
Logic SQL: SELECT * FROM t_order;
SQLStatement: MySQLSelectStatement(limit=Optional.empty, lock=Optional.empty, window=Optional.empty)
Actual SQL: ds_0 ::: SELECT * FROM t_order_0 ORDER BY order_id ASC ;
Actual SQL: ds_0 ::: SELECT * FROM t_order_1 ORDER BY order_id ASC ;
Actual SQL: ds_1 ::: SELECT * FROM t_order_0 ORDER BY order_id ASC ;
Actual SQL: ds_1 ::: SELECT * FROM t_order_1 ORDER BY order_id ASC ;
复制代码
从上面能大致看的处理,分片策略是起效的
接着运行下面的示例,记得环境 ShardingSphere Proxy 的配置
读写分离
1.数据库初始化
用下面的语句建立相关的数据库
CREATE SCHEMA IF NOT EXISTS demo_write_ds;
CREATE SCHEMA IF NOT EXISTS demo_read_ds_0;
CREATE SCHEMA IF NOT EXISTS demo_read_ds_1;
CREATE TABLE IF NOT EXISTS demo_read_ds_0.t_order (order_id BIGINT NOT NULL AUTO_INCREMENT, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_id));
CREATE TABLE IF NOT EXISTS demo_read_ds_1.t_order (order_id BIGINT NOT NULL AUTO_INCREMENT, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_id));
CREATE TABLE IF NOT EXISTS demo_read_ds_0.t_order_item (order_item_id BIGINT NOT NULL AUTO_INCREMENT, order_id BIGINT NOT NULL, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_item_id));
CREATE TABLE IF NOT EXISTS demo_read_ds_1.t_order_item (order_item_id BIGINT NOT NULL AUTO_INCREMENT, order_id BIGINT NOT NULL, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_item_id));
复制代码
2.ShardingSphere Proxy 配置
我们放开配置:shardingsphere-proxy/shardingsphere-proxy-bootstrap/src/main/resources/conf/config-readwrite-splitting.yaml
放开其配置即可,然后改改密码,大致如下:
记住我们的数据库是: readwrite_splitting_db
schemaName: readwrite_splitting_db
dataSources:
write_ds:
url: jdbc:mysql://127.0.0.1:3306/demo_write_ds?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
read_ds_0:
url: jdbc:mysql://127.0.0.1:3306/demo_read_ds_0?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
read_ds_1:
url: jdbc:mysql://127.0.0.1:3306/demo_read_ds_1?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
rules:
- !READWRITE_SPLITTING
dataSources:
pr_ds:
writeDataSourceName: write_ds
readDataSourceNames:
- read_ds_0
- read_ds_1
复制代码
配置完成后,重启
3.示例运行
使用官方示例:examples/shardingsphere-proxy-example/shardingsphere-proxy-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/proxy/spring/boot/mybatis/ProxySpringBootStarterExample.java
要修改下配置:examples/shardingsphere-proxy-example/shardingsphere-proxy-boot-mybatis-example/src/main/resources/application.properties
将数据库名改成 readwrite_splitting_db,大致如下:
mybatis.config-location=classpath:META-INF/mybatis-config.xml
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3307/readwrite_splitting_db?useServerPrepStmts=true&cachePrepStmts=true
spring.datasource.username=root
spring.datasource.password=root
复制代码
然后启动,我们就看到日志,日志是 ShardingSphere Proxy 的:
SQLStatement: MySQLInsertStatement(setAssignment=Optional.empty, onDuplicateKeyColumns=Optional.empty)
Actual SQL: write_ds ::: INSERT INTO t_order_item (order_id, user_id, status) VALUES (?, ?, ?); ::: [20, 10, INSERT_TEST]
Logic SQL: select @@session.transaction_read_only
SQLStatement: MySQLSelectStatement(limit=Optional.empty, lock=Optional.empty, window=Optional.empty)
Actual SQL: read_ds_0 ::: select @@session.transaction_read_only
Logic SQL: SELECT * FROM t_order;
SQLStatement: MySQLSelectStatement(limit=Optional.empty, lock=Optional.empty, window=Optional.empty)
Actual SQL: read_ds_1 ::: SELECT * FROM t_order
复制代码
从上面的日志可以看出,写入是成功了的,查询的时候也走了从库,说明我们的读写分离是有效的
但也证明我们昨天的读写分离失败了,这个后面得研究下
在启动也报了个错:Column index out of range.
感觉是示例问题,暂时不管(其实尝试搞了下,没搞定,哎)
这不测试完了,尝试下一个的时候,记得将配置还原
数据加密
1.数据库初始化
执行下面的语句对数据库进行初始化:
CREATE SCHEMA IF NOT EXISTS demo_ds_0;
CREATE SCHEMA IF NOT EXISTS demo_ds_1;
复制代码
2.ShardingSphere Proxy 配置
放开加密配置:shardingsphere-proxy/shardingsphere-proxy-bootstrap/src/main/resources/conf/config-encrypt.yaml
声明了数据库名称:encrypt_db
对下面两个字段进行加密:user_id/order_id
配置大致如下:
schemaName: encrypt_db
dataSources:
ds_0:
url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
ds_1:
url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
rules:
- !ENCRYPT
encryptors:
aes_encryptor:
type: AES
props:
aes-key-value: 123456abc
md5_encryptor:
type: MD5
tables:
t_encrypt:
columns:
user_id:
plainColumn: user_plain
cipherColumn: user_cipher
encryptorName: aes_encryptor
order_id:
cipherColumn: order_cipher
encryptorName: md5_encrypto
复制代码
配置修改后,进行重启(记得其他配置文件的配置要注释掉)
3.示例运行
修改配置:examples/shardingsphere-proxy-example/shardingsphere-proxy-boot-mybatis-example/src/main/resources/application.properties
修改数据库密码和数据库名为:encrypt_db
大致配置为:
mybatis.config-location=classpath:META-INF/mybatis-config.xml
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3307/encrypt_db?useServerPrepStmts=true&cachePrepStmts=true
spring.datasource.username=root
spring.datasource.password=root
复制代码
运行启动,从日志看到我们确实跑起来,日志看起来也是正常
总结
本篇文件使用 ShardingSphere Proxy,单独运行尝试了数据分片、数据加密、读写分离
在示例中,好像三者是分离的,不同的配置文件,不同的逻辑数据库名称
那三者能结合或者两两组合吗,从文档上来看,应该是可以,后面探索下
评论