一. 简介
Sharding-Proxy是ShardingSphere的第二个产品。
它定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持。
目前先提供MySQL/PostgreSQL版本,它可以使用任何兼容MySQL/PostgreSQL协议的访问客户端(如:MySQL Command Client, MySQL Workbench, Navicat等)操作数据,对DBA更加友好。
- 向应用程序完全透明,可直接当做MySQL/PostgreSQL使用。
- 适用于任何兼容MySQL/PostgreSQL协议的的客户端。
二.对比
Sharding-JDBC | Sharding-Proxy | Sharding-Sidecar | |
---|---|---|---|
数据库 | 任意 | MySQL/PostgreSQL | MySQL/PostgreSQL |
连接消耗数 | 高 | 低 | 高 |
异构语言 | 仅Java | 任意 | 任意 |
性能 | 损耗低 | 损耗略高 | 损耗低 |
无中心化 | 是 | 否 | 是 |
静态入口 | 无 | 有 | 无 |
Sharding-Proxy的优势在于对异构语言的支持,以及为DBA提供可操作入口。它可以屏蔽底层分库分表的复杂度,运维及开发人员仅面向proxy操作,像操作单个数据库一样操作复杂的底层MySQL实例
三.Sharding-Proxy的使用
1.下载
官网的下载通道下载,也可以下载shardingsphere的源码
本文两者都用了,主要是存在部分问题。先使用下载的包
2.启动及配置
(1)配置
- cd 到bin目录下
按照需要将配置放入对应的文件,在server.yaml中配置服务治理相关逻辑
- Server.yaml配置
orchestration:
registry:
orchestrationType: registry_center,config_center # 设置组件的治理类型,即使配置中心,又是注册中心
instanceType: zookeeper # 具体的组件实现
serverLists: 127.0.0.1:2181 # 组件实例地址,多个使用英文逗号隔开
namespace: sharding-namespace # 命名空间,为了区分的,
props:
overwrite: false # 是否开启启动覆盖远程配置,我们使用的proxy主要是查业务配置的数据库集群,以业务配置的为准,这里是选择false
retryIntervalMilliseconds: 500
timeToLiveSeconds: 60
maxRetries: 3
operationTimeoutMilliseconds: 500
authentication: # 权限相关配置
users:
root:
password: root # 这套账号就像是mysql的root账号,拥有所有【逻辑数据库】权限,注意是【逻辑数据库】
sharding:
password: sharding
authorizedSchemas: logic_db # 这套账号指定了【逻辑数据库】权限只有logic_db,既然是逻辑数据库,自定义的
props:
max.connections.size.per.query: 1
acceptor.size: 16 # The default value is available processors count * 2.
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
proxy.opentracing.enabled: false
proxy.hint.enabled: false
query.with.cipher.column: false
sql.show: true
allow.range.query.with.inline.sharding: true
配置说明:
- 治理实例名称保持和【服务治理】一文中一致
- 这里的命名空间是在【服务治理一文中】的业务端定义的命名空间,这样就可以直接使用之前定义的策略,服务治理中使用的是读写分离+分库分表的策略
- 指定的Schemas同样是【服务治理】一文中中业务定义的schemas,查下zookeeper
这个logic_db,就是上文注册的【逻辑数据源名称】,当业务没有定义schema的名称时,默认【逻辑数据源名称】就是logic_db,旁边的sharding_db是我自定测试的,关于【服务治理】参考ShardingSphere应用专题–4.1.1版本–Sharding-JDBC分布式治理(十四)
当然,使用Sharding-UI查看更直观,关于Sharinding-UI部分内容请参考ShardingSphere应用专题–4.1.1版本–Sharding-UI的使用(十五)
如果没有使用服务治理,则需要按照配置文件的demo,自行配置其他config-*.yaml,这里就不再演示了
这样,服务,proxy以及注册中心的关系是这样的:
proxy只拉取Service的配置,不修改,这样,基于服务治理的动态刷新机制,服务的配置一旦修改生效,proxy也将将立即生效
(2)确定连接驱动
cd到lib下面,数据库的链接驱动是要自己指定的,我使用的是mysql,所以把mysql的驱动包放入,安装包自行下载5.0以上即可
(3)启动
- 启动start.sh proxy默认的端口号是3307
➜ bin ./start.sh
Starting the Sharding-Proxy ...
The port is 3388
The classpath is /Users/boss/Downloads/apache-shardingsphere-4.1.1-sharding-proxy-bin/conf:.:..:/Users/boss/Downloads/apache-shardingsphere-4.1.1-sharding-proxy-bin/lib/*:/Users/boss/Downloads/apache-shardingsphere-4.1.1-sharding-proxy-bin/lib/*:/Users/boss/Downloads/apache-shardingsphere-4.1.1-sharding-proxy-bin/ext-lib/*
Please check the STDOUT file: /Users/boss/Downloads/apache-shardingsphere-4.1.1-sharding-proxy-bin/logs/stdout.log
- 按照以上提示一定要查看log确认是否启动成功
➜ bin tail -100f ../logs/stdout.log
没有异常,看到ACTICE就表示启动成功了
3.测试
(1)Mysql原生链接测试
mysql -h localhost -P 3307 -uroot -p root
- 这里的proxy代理后,数据库的名字就是authorizedSchemas,这个默认是logic_db
- 把Sharing-UI中的logic_db的配置贴下
defaultDataSourceName: master0
masterSlaveRules:
master0:
masterDataSourceName: master0
name: master0
slaveDataSourceNames:
- slave0
master1:
masterDataSourceName: master1
name: master1
slaveDataSourceNames:
- slave1
tables:
bill:
actualDataNodes: master$->{0..1}.bill_$->{0..1}
databaseStrategy:
inline:
algorithmExpression: master$->{bill_amount % 2}
shardingColumn: bill_amount
keyGenerator:
column: id
props:
worker.id: '123'
type: SNOWFLAKE
logicTable: bill
tableStrategy:
inline:
algorithmExpression: bill_$->{id % 2}
shardingColumn: id
这里只针对了bill做了分库分表的策略。proxy将所有的表都显示了出来。注意这里有个重要的配置【defaultDataSourceName】,如果没有使用该配置,proxy只显示分库分表策略涉及的表,即:只有bill表,以下配置在proxy中不会显示bill_item表(加密的配置会不会显示,有兴趣的可以试试):
1.设置自动分库逻辑
spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=master0
2.设置广播表
spring.shardingsphere.sharding.broadcast-tables=bill_item
以上两种方式都无法在proxy中发现bill_item这个表
尝试查下bill_item;
没有问题,其他更加详细的测试就不在这里说了,自行探索
(2)其他客户端测试(Navicat Premium)
a.填写链接信息
b.自定义Databases
这步必须有。为啥?
当我们通过客户端打开某个数据库,这个时候默认是查询数据库的information_schema。由于sharding_proxy是个代理,直接就会将这个查询数据库元数据的语句打到底层库,返回的将是底层的db0,db1等原始数据库信息,然后当你点击db0时,由于proxy会加工表名,比如bill_0,bill_1这种真实节点,直接会替换成逻辑节点名称bill。这个替换过程是通过配置文件转换的。当proxy读取到db0时,配置文件中根本不存在这个数据库的信息,点击数据库将没有任何反应
可以从proxy的log看到的log佐证这个想法:
这个在官方的issue中有提到,不过不影响使用,看看后面会不会优化吧
a,b操作完成之后,就会看到对应的数据信息
点击bill_item:
c.表名附带库名,非分库分表逻辑表路由错误的bug
[INFO ] 16:32:04.147 [ShardingSphere-Command-3] ShardingSphere-SQL - Actual SQL: slave0 ::: SELECT * FROM `logic_db`.`bill_item` LIMIT 0,1000
这里直接将存在于proxy层面的逻辑库名打到了底层真实库中,是个bug。通过源码阅读发现:
如果使用的是navicat这种插件,table名会带上逻辑库名,即:db.tb,该项在sharding的语法树中是一个节点(表名节点)
当存在需要改写表名的时候,比如分表时,此时分片改写引擎会将表名节点整个替换真实表名(bill_0)
但是一旦不存在分表逻辑是,则.将不会替换,造成sql错误
解决的思路是:如果发现没有分表逻辑,且没有改写逻辑时:强制将表名节点替换为真实表节点。
修改4.1.1版本源代码org.apache.shardingsphere.sharding.rewrite.token.generator.impl.TableTokenGenerator
修改后启动本地的sharding_proxy即可结局navicat链接时,非分库分表无法正常查询的bug。
- 查询语句
- 插入语句
路由数据也没有问题
d.类型不兼容bug
对于正常的sql 即使id是个数字,增加单引号也是不会引起类型转换问题的,这个时候在navicat中测试下:
报错,String没有mod方法,查看源码:
当加上引号后,java内存会将这个id识别成String,而当调用groovy的脚本时,直接调用了String 的mod方法引起了错误
解决方案
查看官方issue,官方给出的解决方案是,在配置中增加强制转换,但是有的人给的是num有的给的是String,为了兼容,采用全部转为String再转Long的方式。
由于现在的配置,proxy和业务端都在用,直接通过注册中心修改即可,且不用重启(动态刷新生产上紧急时使用,但不要忘记服务端配置的是启动覆盖,还要手动同步到服务端)
打开Sharding-UI:
提交后查看:
- proxy
问题解决:
- 服务端(主要看下是否会出问题)
增删改查都没有问题,具体就不贴出来了