使用ProxySql实现MySQL的读写分离
使用ProxySql实现MySQL的读写分离
前言
ProxySQL 是一款高性能、开源的 MySQL 数据库中间件,主要作用是在应用程序与 MySQL 数据库之间搭建一层代理,实现数据库的负载均衡、读写分离、连接池管理、查询路由、故障转移等功能,从而提升数据库集群的可用性、稳定性和性能。
核心功能与作用
-
读写分离
自动将 SQL 查询请求分发到不同的数据库节点:- 写操作(如
INSERT
、UPDATE
)路由到主库(Master)。 - 读操作(如
SELECT
)分发到从库(Slave),减轻主库压力,提高查询效率。
支持自定义规则(如基于 SQL 语句、用户、表名等)灵活分配请求。
- 写操作(如
-
负载均衡
对于多个从库(或主库集群),ProxySQL 可通过轮询、权重分配等策略,将读请求均匀分发到各节点,避免单节点过载,提升集群整体吞吐量。 -
连接池管理
数据库连接的创建和销毁成本较高,ProxySQL 维护一个连接池,复用已建立的连接,减少连接开销,同时限制连接总数,防止数据库被过多连接压垮。 -
故障检测与自动切换
持续监控数据库节点的健康状态(如通过心跳检测),当主库或从库故障时,自动将请求切换到正常节点,减少人工干预,提高系统可用性。 -
查询缓存与过滤
缓存高频查询结果,减少重复计算;同时可过滤危险 SQL(如DROP
、TRUNCATE
),增强数据库安全性。 -
动态配置与无感知重启
支持在线修改配置(如路由规则、节点权重),无需重启服务,避免业务中断,适合高可用场景。
适用场景
- 中小型 MySQL 集群的读写分离和负载均衡。
- 需要高可用、低延迟的在线业务(如电商、金融)。
- 希望简化数据库集群管理,减少开发层对数据库架构依赖的场景。
与同类工具对比
- MySQL Router:官方工具,配置简单,但功能较少(如无连接池、高级路由)。
- MaxScale:功能丰富,但性能略逊于 ProxySQL,配置相对复杂。
- MyCat:支持多数据库类型,但更侧重分库分表,MySQL 适配性不如 ProxySQL。
ProxySQL 凭借轻量、高性能、灵活的特性,成为 MySQL 中间件的主流选择之一。
安装配置
安装MySQL
懒得安装 随便写了个脚本
mysql.sh
下载Proxysql包
https://github.com/sysown/proxysql/releases
#我使用的是Centos7系统 并且架构是x86虚拟机 可以通过uname -u 查看自己的系统架构根据自己的系统和版本适配下载
安装Proxysql
安装依赖环境
yum install perl-DBD-mysql perl-DBI mysql-community-libs-compat bzip2 -y
-
perl-DBD-mysql
:Perl Database Driver for MySQL,是 Perl 语言访问 MySQL 数据库的驱动程序,ProxySQL 安装和运行过程中可能需要通过 Perl 脚本与 MySQL 进行交互 -
perl-DBI
:Database Interface(数据库接口)模块,为 Perl 程序提供了一个标准的数据库访问接口。ProxySQL 的部分功能可能依赖于 Perl 的 DBI 模块来实现对数据库的操作 -
mysql-community-libs-compat
:当使用 rpm 包方式安装 ProxySQL 时,可能需要安装mysql-community-libs-compat
,否则可能会报错。它提供了与 MySQL 相关的兼容库文件,确保 ProxySQL 与 MySQL 之间的兼容性 - 此外,系统中还应确保安装了bzip2 ,虽然它不是 ProxySQL 直接的功能依赖,但在处理一些压缩文件等操作时可能会用到。同时,也需要安装一个 MySQL 客户端 ,方便后续连接 ProxySQL 进行配置和测试等操作
-
PS:安装前创建一个Proxysql用户和组
安装Proxysql
rpm -ivh proxysql-2.6.3-1-centos7.x86_64.rpm
查看是否启动
netstat -anput | grep proxysql
tcp 0 0 0.0.0.0:6032 0.0.0.0:* LISTEN 7698/proxysql
tcp 0 0 0.0.0.0:6033 0.0.0.0:* LISTEN 7698/proxysql
启动proxysql服务并加入开机自启
systemctl start proxysql
systemctl enable proxysql
二、连接 ProxySQL 管理界面
bash
mysql -uadmin -padmin -h127.0.0.1 -P6032
-
参数解释:
-
-uadmin
:使用用户名admin
登录 -
-padmin
:密码是admin
-
-h127.0.0.1
:连接本地服务器(ProxySQL 管理界面默认只允许本地访问) -
-P6032
:连接 ProxySQL 的管理端口(6032 是 ProxySQL 管理界面的默认端口)
-
-
作用:登录到 ProxySQL 的管理界面,后续所有配置都在这里完成。
三、ProxySQL 管理员账户配置
1. 查看当前管理员账户
sql
Admin> select @@admin-admin_credentials;
- 作用:查看 ProxySQL 当前的管理员账户列表(默认只有
admin:admin
)。
2. 添加新管理员账户
sql
Admin> set admin-admin_credentials='admin:admin;root:root123';
- 作用:添加一个新的管理员账户
root
,密码root123
(分号分隔多个账户)。 - 用途:默认账户只能本地登录,新增账户可用于远程管理(如用 Navicat 连接)。
3. 生效并保存管理员账户配置
sql
Admin> load admin variables to runtime; # 让配置立即生效(临时生效)
Admin> save admin variables to disk; # 保存到磁盘(永久生效,重启不丢失)
- 作用:ProxySQL 的配置需要先加载到内存(runtime)才能生效,再保存到磁盘(disk)才能永久保留。
四、配置监控账号
1. 在 MySQL 主库创建监控用户
sql
CREATE USER 'monitor'@'%' IDENTIFIED BY 'monitor';
GRANT USAGE, REPLICATION CLIENT ON *.* TO 'monitor'@'%';
-
作用:创建一个专门用于监控的 MySQL 用户
monitor
,权限限制为:-
USAGE
:允许登录但无实际操作权限 -
REPLICATION CLIENT
:允许查询主从复制状态(用于 ProxySQL 检测主从是否正常)
-
2. 在 ProxySQL 中配置监控用户
sql
UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-monitor_username';
UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-monitor_password';
- 作用:告诉 ProxySQL“用
monitor
这个用户去监控后端 MySQL 服务器的健康状态”。
五、添加 MySQL 服务器到 ProxySQL
1. 注册主从服务器
sql
-- 添加主服务器(写操作专用)
INSERT INTO mysql_servers(hostgroup_id,hostname,port,weight,comment) VALUES (1,'192.168.8.100',3306,1,'Write group');-- 添加从服务器(读操作专用)
INSERT INTO mysql_servers(hostgroup_id,hostname,port,weight,comment) VALUES (2,'192.168.8.101',3306,1,'Read group');
-
参数解释:
-
hostgroup_id
:服务器组 ID(1 = 写组,2 = 读组,用于区分主从) -
hostname
:MySQL 服务器的 IP 地址 -
port
:MySQL 端口(默认 3306) -
weight
:权重(数值越大,分配的请求越多,默认 1 即可)
-
-
作用:告诉 ProxySQL“有这两台 MySQL 服务器可用,1 号是主库(写),2 号是从库(读)”。
2. 生效并保存服务器配置
sql
LOAD MYSQL SERVERS TO RUNTIME; # 临时生效
SAVE MYSQL SERVERS TO DISK; # 永久保存
- 作用:让 ProxySQL 加载刚才添加的 MySQL 服务器信息。
六、配置数据库访问用户
1. 在 MySQL 主从库创建访问用户
sql
-- 创建管理员用户(有写权限)
CREATE USER 'adm'@'%' IDENTIFIED BY '123456';
GRANT ALL PRIVILEGES ON *.* TO 'adm'@'%';-- 创建只读用户(只有读权限)
CREATE USER 'read'@'%' IDENTIFIED BY '123456';
GRANT SELECT ON *.* TO 'read'@'%';
FLUSH PRIVILEGES; # 刷新权限使配置生效
-
作用:创建两个用户:
-
adm
:有所有权限(用于执行写操作,如新增 / 修改数据) -
read
:只有查询权限(用于执行读操作,如查询数据)
-
-
注意:主从库都要创建这两个用户(因为 ProxySQL 可能会连接任意一台)。
2. 在 ProxySQL 中注册用户
sql
INSERT INTO mysql_users(username,password,default_hostgroup) VALUES ('adm','123456',1); -- adm用户默认用写组(1)
INSERT INTO mysql_users(username,password,default_hostgroup) VALUES ('read','123456',2); -- read用户默认用读组(2)
- 作用:告诉 ProxySQL“有这两个用户会通过你访问 MySQL,
adm
默认走主库,read
默认走从库”。
3. 生效并保存用户配置
sql
LOAD MYSQL USERS TO RUNTIME; # 临时生效
SAVE MYSQL USERS TO DISK; # 永久保存
- 作用:让 ProxySQL 加载用户信息,允许这些用户通过 ProxySQL 访问 MySQL。
七、配置读写分离规则
1. 添加路由规则
sql
-- 规则1:特殊SELECT语句走主库(例如包含UPDATE的查询)
INSERT INTO mysql_query_rules (rule_id,active,match_digest,destination_hostgroup,apply) VALUES (1,1,'^SELECT.*FROM UPDATE$',1,1);-- 规则2:普通SELECT语句走从库
INSERT INTO mysql_query_rules (rule_id,active,match_digest,destination_hostgroup,apply) VALUES (2,1,'^SELECT',2,1);-- 规则3:SHOW语句走从库
INSERT INTO mysql_query_rules (rule_id,active,match_digest,destination_hostgroup,apply) VALUES (3,1,'^SHOW',2,1);
-
参数解释:
-
rule_id
:规则 ID(唯一,用于区分) -
active=1
:启用该规则 -
match_digest
:匹配 SQL 语句的正则表达式(^SELECT
表示以 SELECT 开头的语句) -
destination_hostgroup
:匹配后路由到的服务器组(1 = 主库,2 = 从库) -
apply=1
:匹配后立即应用,不再检查后续规则
-
-
作用:定义 “哪些 SQL 语句走主库,哪些走从库”,实现自动路由。
2. 生效并保存规则
sql
LOAD MYSQL QUERY RULES TO RUNTIME; # 临时生效
SAVE MYSQL QUERY RULES TO DISK; # 永久保存
- 作用:让 ProxySQL 加载刚才设置的路由规则。
八、测试读写分离
1. 测试读操作(通过 read 用户)
bash
mysql -uread -p123456 -h 127.0.0.1 -P6033 -e "SELECT @@hostname,@@port"
-
参数解释:
-
-uread
:用只读用户read
登录 -
-P6033
:连接 ProxySQL 的数据库访问端口(6033 是 ProxySQL 对外提供数据库服务的端口) -
-e
:直接执行后面的 SQL 语句(查询当前连接的服务器主机名和端口)
-
-
预期结果:返回从库(192.168.8.101)的信息,说明读操作走了从库。
2. 测试写操作(通过 adm 用户)
bash
mysql -uadm -p123456 -h 127.0.0.1 -P6033 -e "create database test2;"
- 作用:创建一个数据库(写操作),预期会路由到主库(192.168.8.100)。
3. 查看 ProxySQL 的路由记录
bash
mysql -uadmin -padmin -h127.0.0.1 -P6032 # 登录管理界面
select hostgroup,digest_text from stats_mysql_query_digest\G; # 查看SQL语句的路由记录
-
作用:检查 ProxySQL 是否按规则路由:
-
hostgroup=1
:表示语句走了主库 -
hostgroup=2
:表示语句走了从库
-
九、保存所有配置(防止丢失)
sql
-- 服务器配置
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;-- 查询规则配置
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;-- 用户配置
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;-- 变量配置
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;
- 作用:ProxySQL 的配置默认只在内存中,重启后会丢失。这组命令用于将所有配置永久保存到磁盘,确保服务器重启后配置仍然有效。
总结
整个流程的核心是:
- 安装 ProxySQL 并启动
- 告诉 ProxySQL“有哪些 MySQL 服务器(主从)”
- 告诉 ProxySQL “用什么用户监控这些服务器”
- 告诉 ProxySQL “允许哪些用户通过你访问 MySQL”
- 告诉 ProxySQL“哪些 SQL 语句走主库,哪些走从库”
- 测试并保存配置
通过这些步骤,ProxySQL 就能自动实现 “写操作走主库,读操作走从库” 的读写分离,减轻单台数据库的压力。