简介
在上篇文章中,体验了 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.HikariDataSourcespring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3307/sharding_db?useServerPrepStmts=true&cachePrepStmts=truespring.datasource.username=rootspring.datasource.password=root
复制代码
启动后,我们就看到相关的 ShardingSphere Proxy 的日志:
Logic SQL: select @@session.transaction_read_onlySQLStatement: MySQLSelectStatement(limit=Optional.empty, lock=Optional.empty, window=Optional.empty)Actual SQL: ds_0 ::: select @@session.transaction_read_onlyLogic 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_onlySQLStatement: MySQLSelectStatement(limit=Optional.empty, lock=Optional.empty, window=Optional.empty)Actual SQL: ds_0 ::: select @@session.transaction_read_onlyLogic 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.HikariDataSourcespring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3307/readwrite_splitting_db?useServerPrepStmts=true&cachePrepStmts=truespring.datasource.username=rootspring.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_onlySQLStatement: MySQLSelectStatement(limit=Optional.empty, lock=Optional.empty, window=Optional.empty)Actual SQL: read_ds_0 ::: select @@session.transaction_read_onlyLogic 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.HikariDataSourcespring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3307/encrypt_db?useServerPrepStmts=true&cachePrepStmts=truespring.datasource.username=rootspring.datasource.password=root
复制代码
运行启动,从日志看到我们确实跑起来,日志看起来也是正常
总结
本篇文件使用 ShardingSphere Proxy,单独运行尝试了数据分片、数据加密、读写分离
在示例中,好像三者是分离的,不同的配置文件,不同的逻辑数据库名称
那三者能结合或者两两组合吗,从文档上来看,应该是可以,后面探索下
评论