目录:
安装 ShardingSphere
配置ShardingSphere-JDBC
配置ShardingSphere-Proxy
测试弹性扩容
本次测试基于shardingsphere 5.0.0
安装ShardingSphere
1 2 3 4 5 6 <dependency > <groupId > org.apache.shardingsphere</groupId > <artifactId > shardingsphere-jdbc-core-spring-boot-starter</artifactId > <version > 5.0.0</version > </dependency >
填坑:
1、与druid-spring-boot-starter有冲突,如果还想使用druid连接池可以 将druid-spring-boot-starter 修改为 druid
熟悉配置参数
点击查看官方稳定:Spring Boot Starter
1 2 # 显示sql日志 spring.shardingsphere.props.sql-show=true
点击查看 spring.shardingsphere.props支持属性
也可以参考:org.apache.shardingsphere.infra.config.properties.ConfigurationPropertyKey
填坑:
1 2 3 4 5 # 5.x以前 spring.shardingsphere.props.sql.show=true # 5.x 及以后 spring.shardingsphere.props.sql-show=true
数据源配置
点击查看官方稳定
1 2 3 4 5 6 7 8 9 10 spring.shardingsphere.datasource.names= # 真实数据源名称,多个数据源用逗号区分 # <actual-data-source-name> 表示真实数据源名称 spring.shardingsphere.datasource.<actual-data-source-name>.type= # 数据库连接池全类名 spring.shardingsphere.datasource.<actual-data-source-name>.driver-class-name= # 数据库驱动类名,以数据库连接池自身配置为准 spring.shardingsphere.datasource.<actual-data-source-name>.jdbc-url= # 数据库 URL 连接,以数据库连接池自身配置为准 spring.shardingsphere.datasource.<actual-data-source-name>.username= # 数据库用户名,以数据库连接池自身配置为准 spring.shardingsphere.datasource.<actual-data-source-name>.password= # 数据库密码,以数据库连接池自身配置为准 spring.shardingsphere.datasource.<actual-data-source-name>.<xxx>= # ... 数据库连接池的其它属性
分库配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # 配置 tb_news 表规则 spring.shardingsphere.rules.sharding.tables.tb_news.actual-data-nodes=ds$->{0..1}.tb_news ## 配置分库策略 spring.shardingsphere.rules.sharding.tables.tb_news.database-strategy.standard.sharding-column=id # 可以设置 suanfa-1、suanfa-2 spring.shardingsphere.rules.sharding.tables.tb_news.database-strategy.standard.sharding-algorithm-name=suanfa-1 # 配置算法 # 取模 spring.shardingsphere.rules.sharding.sharding-algorithms.suanfa-1.type=MOD spring.shardingsphere.rules.sharding.sharding-algorithms.suanfa-1.props.sharding-count=2 # 行内+表达式模式 # 返回数据源名称、或者表名称 spring.shardingsphere.rules.sharding.sharding-algorithms.suanfa-2.type=INLINE spring.shardingsphere.rules.sharding.sharding-algorithms.suanfa-2.props.algorithm-expression=ds$->{id.toInteger() % 2}
填坑
错误1:
1 2 3 4 5 6 Cause: java.lang.IllegalStateException: All tables must be in the same datasource.] with root cause
错误2:
1 2 3 4 5 6 7 select n.*,t.name as type_name from org.apache.shardingsphere.sharding.rewrite.token.pojo.TableToken@377c0f4 n left join org.apache.shardingsphere.sharding.rewrite.token.pojo.TableToken@1b484898 t on t.id=n.type_id -- 策略不同导致 两个表在不同的db中,需要确保tb_news 与tb_news_type 拥有相同的策略 spring.shardingsphere.rules.sharding.tables.tb_news_type.actual-data-nodes=ds$->{0..1}.tb_news_type spring.shardingsphere.rules.sharding.binding-tables=tb_news,tb_news_type
延伸
1、不拆分的、但被拆分表关联查询(news_type ),那该怎么处理呢?
1 2 3 ## 公共表 spring.shardingsphere.rules.sharding.broadcast-tables=tb_news_type
2、不拆分、且不被拆分表关联查询的,如何配置?
1 2 # 不用配置,shardingphere会自动识别应该用哪个库
加密字段
配置算法:
1 2 3 4 # 加密算法配置 spring.shardingsphere.rules.encrypt.encryptors.aes.type=AES spring.shardingsphere.rules.encrypt.encryptors.aes.props.aes-key-value=111111222222 spring.shardingsphere.rules.encrypt.queryWithCipherColumn=false
场景1:对pwd 字段 进行 写入时自动加密,读取时自动解密;
1 2 3 4 5 6 # 对 pwd 列自动加密、解密 spring.shardingsphere.rules.encrypt.tables.tb_news.query-with-cipher-column=true # 加密列名称 spring.shardingsphere.rules.encrypt.tables.tb_news.columns.pwd.cipher-column=pwd # 加密算法名称 spring.shardingsphere.rules.encrypt.tables.tb_news.columns.pwd.encryptor-name=aes
场景2:同时存储明文、密文列author、author_enc
1 2 3 4 5 6 # 加密列名称 spring.shardingsphere.rules.encrypt.tables.tb_news.columns.author.cipher-column=author_enc # 原文列名称 spring.shardingsphere.rules.encrypt.tables.tb_news.columns.author.plain-column=author # 加密算法名称 spring.shardingsphere.rules.encrypt.tables.tb_news.columns.author.encryptor-name=aes
填坑:
1 2 3 # 写数据报错 # 配置查询列名称 spring.shardingsphere.rules.encrypt.tables.tb_news.columns.author.assisted-query-column=xxxx
1 2 3 4 # 查询报错 # 存在同时 存储明文、密文 的列时 # 开启对加密字段的查询(自动解密) # spring.shardingsphere.rules.encrypt.tables.tb_news.query-with-cipher-column=true
总结下来:
同一个表 有同时存储明文、密文的字段时,query-with-cipher-column 一定时FALSE;
读写分离
1 2 3 4 5 6 7 8 9 10 11 12 # 负载均衡算法配置 # 负载均衡算法类型 RANDOM spring.shardingsphere.rules.readwrite-splitting.load-balancers.random.type=RANDOM # 为ds0配置读写规则 # 写库 ds0 spring.shardingsphere.rules.readwrite-splitting.data-sources.ds0.write-data-source-name=ds0 # 读库 ds11\ds12\ds13 spring.shardingsphere.rules.readwrite-splitting.data-sources.ds0.read-data-source-names=ds11,ds12,ds13 # 读库负载均衡规则 spring.shardingsphere.rules.readwrite-splitting.data-sources.ds0.load-balancer-name=random
填坑:
1、shardingphere不负责同步数据,需要用其他机制例如:mysql主从同步
2、所有数据源都需要再spring.shardingsphere.datasource.names 进行声明、否则不会加载
影子库
待完善
分布式事务
待完善,同一个线程内 基础的事务就可以满足;
1 2 3 4 5 6 7 8 9 10 11 12 @Transactional(rollbackFor = Exception.class) @Override public boolean save (NewsEntity entity) { super .save(entity); statsService.ince(key); do others if (false ) { throw new RuntimeException ("xxx" ); } return true ; }
启用ShardingSphere-Proxy
测试弹性库容、需要基于Proxy进行;
下载Proxy
下载源码编译:
1 2 3 4 5 6 7 8 git clone https://gitee.com/Sharding-Sphere/sharding-sphere.git cd sharding-sphere mvn clean install -Dmaven.javadoc.skip=true -Dcheckstyle.skip=true -Drat.skip=true -Djacoco.skip=true -DskipITs -DskipTests -Prelease mv shardingsphere-distribution/shardingsphere-proxy-distribution/target/apache-shardingsphere-5.0.1-SNAPSHOT-shardingsphere-proxy-bin.tar.gz /mnt/d/application/
直接下载:
1 # 下载地址:https://github.com/apache/shardingsphere/archive/refs/tags/5.0.0.tar.gz
配置Proxy
解压软件
1 2 3 cd /mnt/d/application/ # 解压文件 tar -zxvf apache-shardingsphere-5.0.1-SNAPSHOT-shardingsphere-proxy-bin.tar.gz
修改conf/server.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 # 打开所有配置的注解 # # 修改 mode mode: type: Standalone repository: type: File props: path: /mnt/d/sharding_config.yaml overwrite: true # 其他保持不变
修改 conf/config-sharding.yaml
1 2 3 4 # 打开mysql相关配置注解 # 修改 对应数据源 # 修改 对应表的规则
启动Proxy
1 2 3 4 5 6 ## 参考:https://shardingsphere.apache.org/document/5.0.0/cn/quick-start/shardingsphere-proxy-quick-start/ bin/start.sh # 查看启动日志 tail -f logs/stdout.log
登录Proxy
1 2 3 4 # 注意 用localhost 会直接链接到mysql里面而非 proxy ,用127.0.0.1 替换 # mysql -u${proxy_username} -p${proxy_password} -h${proxy_host} -P${proxy_port} mysql -uroot -proot -hlocalhost -P 3307
弹性扩容
确定scaling是否可用
1 2 3 4 5 6 7 8 9 10 11 12 13 # 在mysql客户端 show scaling list ; # 提示 Empty set (0.05 sec) 、可用 # 提示 mode 必须配置 ,修改server.xml配置文件 # 必须时cluster模式 mode.type = Cluster # Cluster模式无法启动 # wsl 下 IpUtil.getIp 无法获取 ip # 在 cmd 中启动
弹性扩容案例
默认数据源以配置文件形式存在
1 conf/config-sharding.yaml
数据源调整
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # 显示数据源 SHOW SCHEMA RESOURCES ; ADD RESOURCE ds_20 ( URL="jdbc:mysql://127.0.0.1:3306/test20?serverTimezone=UTC&useSSL=false", USER=root, PASSWORD=root, PROPERTIES("maximumPoolSize"=10,"idleTimeout"="30000") ); ADD RESOURCE ds_21 ( URL="jdbc:mysql://127.0.0.1:3306/test21?serverTimezone=UTC&useSSL=false", USER=root, PASSWORD=root, PROPERTIES("maximumPoolSize"=10,"idleTimeout"="30000") ); ADD RESOURCE ds_22 ( URL="jdbc:mysql://127.0.0.1:3306/test22?serverTimezone=UTC&useSSL=false", USER=root, PASSWORD=root, PROPERTIES("maximumPoolSize"=10,"idleTimeout"="30000") );
算法调整
1 2 3 4 5 6 7 # 非必须、自动分表时不需要 #显示算法 show SHARDING ALGORITHMS; #增加算法 CREATE SHARDING ALGORITHM data_mod(TYPE(NAME=MOD,PROPERTIES("sharding-count"=20)))
分片调整
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #显示算法 show SHARDING TABLE RULES; # 修改tb_news 分片算法 ALTER SHARDING TABLE RULE tb_news ( DATANODES("ds_20.tb_news"), DATABASE_STRATEGY(TYPE=standard,SHARDING_COLUMN="id",SHARDING_ALGORITHM="data_mod"), TABLE_STRATEGY(TYPE=standard,SHARDING_COLUMN="id",SHARDING_ALGORITHM="tb_news_inline"), GENERATED_KEY(COLUMN=id,TYPE(NAME=snowflake,PROPERTIES("worker-id"=123))) ); # 自动分片算法 ALTER SHARDING TABLE RULE tb_news ( RESOURCES("ds_20","ds_21","ds_22"), SHARDING_COLUMN="id", TYPE(NAME=hash_mod , PROPERTIES("sharding-count"=10)), GENERATED_KEY(COLUMN=id,TYPE(NAME=snowflake,PROPERTIES("worker-id"=123))) );
同步任务
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 31 32 33 # 任务列表 show scaling list; # 任务详情 show scaling status {jobId}; # 查看算法是否生效 preview select count(1) from tb_news; # 何时算是完成扩容? # 全量数据迁移完成、增量数据迁移完成 # 何时切换到新的规则? # 任务完成数据校验后,会自动迁移到新的规则;也可以手动完成; 正常流程: # 1.1、校验数据 check scaling {jobId}; #1.2、切换数据源 checkout scaling {jobId} # >>Data consistency check not finished or failed. #手动停止 stop scaling {jobId} #需要的话可以再开启 start scaling {jobId} #不需要就删掉 drop scaling {jobId}
坑位:
1、广播表 没有自动同步;
2、增量同步只支持mysql 5.1-5.7 的版本;
3、切换数据源 必须先进行检查
4、直接删除废旧的规则也能触发自动切换数据源
1 2 #删除旧的分片算法后生效的 drop sharding algorithm database_inline;