上一篇文章介绍了mysql如何设置成主从复制模式,而主从复制的目的,是为了读写分离。
读写分离,拿spring boot项目来说,可以有2种方式:
1)设置2个数据源,读和写分开使用
2)使用中间件,如proxysql。它会根据sql语句自动匹配到主、从库
方式一好处是灵活,可控,缺点是需要自己写一点代码,已有的项目修改可能比较大;proxysql的话,还是跟之前一样,只有一个数据源,代码好像也不用改。问题是,我用了一下,感觉有一些坑。也许是还不懂得怎么使用的缘故。
以下是步骤和一些坑:
一、安装proxysql
proxysql是一个中间件,需要安装。安装好了之后,可以把它看作一个mysql,因为它是一个伪装成mysql的中介。你看看,这个”“mysql数据源”:
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.10.249:6033/testdb?characterEncoding=utf-8&useSSL=false&serverTimezone=Hongkong&allowPublicKeyRetrieval=trueusername: workpassword: 123456 # 你的数据库密码
其中 192.168.10.249:6033
就是proxysql的地址。简直了。
1、安装
还是跑在docker里。拉取 ProxySQL Docker 镜像
sudo docker pull proxysql/proxysql
2、在mysql主库中创建监控用户
sudo docker exec -it mysql-1 /bin/bashmysql -uroot -pdata2025--监控账号与默认保持一致最保险(monitor/monitor)
create user 'monitor' identified WITH mysql_native_password by 'monitor';-- 授予监控用户必要的权限
GRANT USAGE ON *.* TO monitor@'%';-- 刷新权限
FLUSH PRIVILEGES;
3、准备配置文件
mkdir /home/admin/proxysql
然后在该文件夹下创建配置文件:proxysql.cnf
admin_variables = {admin_credentials = "admin:admin"mysql_ifaces = "0.0.0.0:6032"
}mysql_variables = {threads = 4max_connections = 2048default_query_delay = 0default_query_timeout = 36000000have_compress = truepoll_timeout = 2000interfaces = "0.0.0.0:6033"default_schema = "information_schema"stacksize = 1048576server_version = "8.0.23"monitor_history=60000monitor_connect_interval=200000monitor_ping_interval=200000
}mysql_servers = ({ address = "mysql-1", port = 3306, hostgroup = 0,weight=1, max_connections = 1000 },{ address = "mysql-2", port = 3306, hostgroup = 1, weight=1,max_connections = 1000 }
)mysql_users = ({ username = "work", password = "123456", default_hostgroup = 0, active = 1 }
)mysql_query_rules = ({ rule_id = 1, active = 1, match_digest = "^SELECT.*", destination_hostgroup = 1, apply = 1 },{ rule_id = 2, active = 1, match_digest = "^(INSERT|UPDATE|DELETE|REPLACE).*", destination_hostgroup = 0, apply = 1 }
)
4、创建 docker 容器
跟mysql的主库、从库共用一个docker网络:mysql-tier。详见上一篇《设置mysql的主从复制模式》
sudo docker run -d \--name proxysql \--network mysql-tier \-p 6032:6032 \-p 6033:6033 \-v /home/admin/proxysql/proxysql.cnf:/etc/proxysql.cnf \-v /home/admin/proxysql/data:/var/lib/proxysql \proxysql/proxysql \proxysql --initial -f -c /etc/proxysql.cnf
5、操作连接
可读可写,very good。
但是,可别高兴得太早。我在里面遇到了一些坑:
二、遇到的坑
1、监控账号
proxysql为了监控mysql,需要mysql提供一个监控账号,该账号权限不用太多,据说只需USAGE即可(见前面脚本)。问题是,这个监控账号,最好是与默认保持一致,即账号名和密码都是monitor。如果改成其他,真不知道在哪里设置。豆包信誓旦旦地说在配置文件里设置,而通义千问则说配置文件里设不了,应该在命令行里写。结果两个都无效,proxysql总是提示无法连接mysql。搞来搞去,我只好将monitor账号的密码改为"monitor",与默认保持一致,就好了。
2、mysql版本问题
mysql8之后,取消了"query_cache_size"这个属性,如果配置文件中关于mysql的版本设置得不对,比如,我之前写的是 5.0.0,就会报这个错。把配置文件提交给AI,它也看不出问题所在。
3、一个库故障后整个proxysql无法使用
在主库、从库都正常的情况下,用了一下,好像没啥问题。
但为了测试,我手动将从库关停后,结果整个proxysql都没办法使用了。proxysql其实已经检测到某个库出了问题,但不知道为什么,它没有将该库的状态设为离线或停止,仍然显示为"ONLINE"。
我在AI上问来问去,通义千问也,豆包也,chatGPT也,都问不出一个子丑寅卯。它们总喜欢穷举一些原因,我不得不一再强调,网络没有问题,在主从库都正常的情况下一切正常,然后它就说,既然如此,那问题很有可能出在proxysql的配置上,巴拉巴拉巴拉,吐出一大堆文字。并且不是一下子吐出,而是装叉地一行一行地输出,以为在拍黑客电影。
proxysql最大的问题,根本不知道它的配置文件应该怎么写,怎么设置参数,官网上也找不到一个例子。
革命尚未成功,先记录下来。