ProxySQL是一个高性能的MySQL中间件,能够代理数百台MySQL服务器,支持数十万的并发连接。ProxySQL代理MySQL并提供读写分离,查询重写和数据分片等功能。
这篇文章主要介绍用Docker Compose编排用ProxySQL实现MySQL集群上读写分离的实践过程。
Docker Compose编排中使用了一个现有镜像,就是breeze2/proxysql。
本次实践源码上传在GitHub的breeze2/mysql-proxy-docker。
Docker Compose编排
这个编排主要实现一主两从的一个MySQL集群和一个ProxySQL代理,ProxySQL代理MYSQL集群的数据请求并且进行读写分离。
目录结构
1 | L--mysql-proxy-docker //主目录 |
docker-compose.yml
1 | version: "2" |
这里配置了四个容器服务,一个breeze2/proxysql
,负责代理各个数据库;三个mysql
,其中一个是主库,另外两个是从库。每个容器服务都指定了静态IP,即使服务重启也不会出现IP错乱问题。proxysql
容器的6032
是提供管理服务的端口,只对Docker宿主机本地IP开放,而6033
是代理数据请求的端口,可以对Docker宿主机网络IP开放。
环境参数
parameters.env
1 | MYSQL_ROOT_PASSWORD=123456 |
数据库配置
这里简单的配置一下各个数据库数据复制备份相关的参数
主库,mysql_node0/conf/my.cnf
1 | [mysqld] |
从库,mysql_node1/conf/my.cnf
1 | [mysqld] |
从库,mysql_node2/conf/my.cnf
1 | [mysqld] |
ProxySQL配置
proxysql/conf/pr.cnf
1 | datadir="/tmp" |
实际运行
在主目录下执行docker-compose up -d
构建并运行整个Docker服务。
开启主从复制
在主目录下执行:
1 | $ sh ./scripts/mysql_set_users_and_repls.sh |
实际上是调用了挂载在数据库容器里的一些脚本:
1 | volumes/share/scripts/msyql_grant_proxysql_users.sh #设置给proxysql用的账号,pr_auser和pr_muser |
脚本里的执行命令都很简单,一看就明。
开启ProxySQL代理
构建整个服务的时候,proxysql
会先挂载主目录下的./volumes/proxysql/conf/pr.cnf
到容器内/etc/proxysql/pr.cnf
,然后执行proxysql -f -c /etc/proxysql/pr.cnf
,所以这里的ProxySQL是按照pr.cnf
里面的配置开启MySQL代理服务的,请仔细阅读上面ProxySQL配置。若有需要在ProxySQL运行的过程中修改配置,可以登录ProxySQL的管理系统操作。
ProxySQL管理系统
在Docker宿主机上登录ProxySQL管理系统(Docker宿主机需要装有MySQL Client):
1 | $ mysql -u admin2 -padmin2 -h 127.0.0.1 -P60320 |
在ProxySQL管理系统上添加一个mysql_user(注意这个testing账号是各个数据库都已建立的,具体查看上面环境参数):
1 | mysql> INSERT INTO mysql_users(username, password, default_hostgroup) VALUES ('testing', 'testing', 2); |
确认是否已添加:
1 | mysql> SELECT * FROM mysql_users; |
把当前修改(MEMORY层)加载到正在运行的ProxySQL(RUNTIME层):
1 | mysql> LOAD MYSQL USERS TO RUNTIME; |
在Docker宿主机上确认ProxySQL是否已加载最新配置:
1 | $ mysql -u testing -ptesting -h 127.0.0.1 -P60330 |
若想ProxySQL重启后依然是当前配置,要把当前修改(MEMORY层)保存到ProxySQL的Sqlite数据库里(DISK层):
1 | mysql> SAVE MYSQL USERS TO DISK; |
ProxySQL配置系统分三层,分别是MEMORY层、RUNTIME层和DISK层。ProxySQL管理系统操作的是MEMORY层,当前ProxySQL运行的是RUNTIME层,保存在ProxySQL本地Sqlite数据库里的是DISK层,详情请阅读文档ProxySQL Configuration。
SysBench测试工具
SysBench是一个脚本化、多线程的基准测试工具,经常用于评估测试各种不同系统参数下的数据库负载情况。
SysBench的使用教程可以参考sysbench 0.5使用手册。
这里使用SysBench-v1.0.9来对ProxySQL进行测试。
SysBench Test Prepare
首先,做测试准备:
1 | $ sysbench /usr/local/Cellar/sysbench/1.0.9/share/sysbench/oltp_read_write.lua --threads=5 --max-requests=0 --time=36 --db-driver=mysql --mysql-user=pr_auser --mysql-password='pr_apass' --mysql-port=60330 --mysql-host=127.0.0.1 --mysql-db=testing --report-interval=1 prepare |
注意,/usr/local/Cellar/sysbench/1.0.9/share/sysbench/oltp_read_write.lua
文件可以在SysBench安装包里找到,执行命令后,会在主库testing数据库里生成一个sbtest1表并插入一些数据,
在从库里一样可以看到testing数据库下有sbtest1表,说明主从复制已生效。
SysBench Test Run
然后,开始读写测试:
1 | $ sysbench /usr/local/Cellar/sysbench/1.0.9/share/sysbench/oltp_read_write.lua --threads=5 --max-requests=0 --time=36 --db-driver=mysql --mysql-user=pr_auser --mysql-password='pr_apass' --mysql-port=60330 --mysql-host=127.0.0.1 --mysql-db=testing --report-interval=1 run |
查看结果
登录ProxySQL管理系统,查看统计结果:
1 | $ mysql -u admin2 -padmin2 -h 127.0.0.1 -P60320 |
可以看到读操作都发送给了hostgroup=1组,写操作都发送给了hostgroup=0组,说明读写分离已生效,读写分离配置请仔细阅读上面ProxySQL配置mysql_query_rules部分。
此致
到此,用Docker实现MySQL ProxySQL读写分离已完成。另外ProxySQL提供的查询重写功能,其实是利用mysql_query_rules配置,对接收到的查询语句进行正则替换,再传递给数据库服务器,详情请阅读文档ProxySQL Configuration中的“MySQL Query Rules”部分;而数据分片功能,在真实数据分片的基础上,再结合mysql_query_rules配置,重写query到正确的主机、数据库或表上,详细内容可以阅读MySQL Sharding with ProxySQL。