MySQL读写分离全面解析:ProxySQL配置指南(十)

本文档详细介绍了使用ProxySQL中间件实现MySQL数据库读写分离的完整配置流程。内容包括读写分离的基本概念、ProxySQL的工作原理、安装部署步骤以及多种配置方法(基于SQL语句、端口和用户的路由策略)。通过本指南,可以学习如何搭建高可用的数据库读写分离架构,有效分担主库压力,提升数据库系统的整体性能和可用性。

一、读写分离概述

  • 数据库主从架构或高可用架构时,都可以有效保障数据库逻辑故障或物理故障对业务的影响;

  • 但是,这两种架构在应用时,业务访问都是访问数据库主节点,进行读写操作。当并发量大时会对主节点造成压力。

  • 因此,可以设计一种新型的业务访问架构方式,可以实现将写数据请求发送到主节点,将读数据请求发送到从节点;

  • 最终,可以有效减少主节点的业务访问压力,这样设计的数据库架构称之为读写分离架构;

二、读写分离原理分析

读写分离架构最终目的:实现业务写操作的请求到达主库,读的操作请求到达从库,从而减少主库的压力,实现不同请求的压力分担。

proxySQL是基于MySQL的一款开源的中间件的产品,是一个灵活的MySQL代理层,可以实现读写分离:

  • proxySQL数据库中间件支持Query路由功能;
  • pxoxySQL数据库中间件支持动态指定某个SQL进行缓存;
  • proxySQL数据库中间件支持动态加载配置信息(无需重启ProxySQL服务)
  • proxySQL数据库中间件支持故障切换和SQL的过滤功能(安全机制)

ProxySQL的参考网站连接:

三、读写分离架构搭建

1.proxySQL中间件安装
sh 复制代码
#下载地址
https://github.com/sysown/proxysql/releases
#安装
[root@db03 ~]# rpm -ivh proxysql-2.4.6-1-centos7.x86_64.rpm 

# 启动运行软件
[root@db03 ~]# systemctl start proxysql
[root@db03 ~]# netstat -lntup
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name         
tcp        0      0 0.0.0.0:6032            0.0.0.0:*               LISTEN      2541/proxysql       
tcp        0      0 0.0.0.0:6033            0.0.0.0:*               LISTEN      2541/proxysql 
-- 启动生成的6032端口为管理端口,用于配置数据库中间件的功能信息连接此端口
-- 启动生成的6033端口为访问端口,用于提供对外的业务访问此端口
2.读写分离软件管理配置
01 proxysql的管理终端

连接进入6032端口之后,表示进行proxysql的管理终端环境,终端环境中会加载五个重要的功能库:

序号 库信息 配置信息 解释说明
01 main mysql_servers 表示后端可以连接mysql服务器的列表
mysql_users 表示配置后端数据库的连接账号和监控账号
mysql_query_rules 表示指定query路由到后端不同服务器的规则列表
mysql_replication_hostgroups 表示节点分组配置信息,可以配置多个写或读节点到一个组中
02 disk 表示持久化的磁盘配置信息
03 stats 表示统计信息的汇总
04 monitor 表示监控收集的信息,比如数据库的监控状态等
05 stats_history 表示收集的有关软件内部功能的历史指标

说明:一般服务是通过配置文件保存功能配置信息,proxySQL是通过数据库中的表进行配置信息的存储设置;

sh 复制代码
# 连接进入到proxySQL管理终端
[root@db03 ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032
...
Your MySQL connection id is 1
Server version: 5.5.30 (ProxySQL Admin Module)
...
# 查看proxySQL终端数据库信息
db03 [(none)]>show databases;
+-----+---------------+-------------------------------------+
| seq | name          | file                                |
+-----+---------------+-------------------------------------+
| 0   | main          |                                     |
| 2   | disk          | /var/lib/proxysql/proxysql.db       |
| 3   | stats         |                                     |
| 4   | monitor       |                                     |
| 5   | stats_history | /var/lib/proxysql/proxysql_stats.db |
+-----+---------------+-------------------------------------+

# 查看proxySQL终端数据表信息
db03 [(none)]>show tables ;
+----------------------------------------------------+
| tables                                             |
+----------------------------------------------------+
| global_variables                                   |
| mysql_aws_aurora_hostgroups                        |
| mysql_collations                                   |
| mysql_firewall_whitelist_rules                     |
| mysql_firewall_whitelist_sqli_fingerprints         |
| mysql_firewall_whitelist_users                     |
| mysql_galera_hostgroups                            |
| mysql_group_replication_hostgroups                 |
| mysql_query_rules                                  |
| mysql_query_rules_fast_routing                     |
| mysql_replication_hostgroups                       |
| mysql_servers                                      |
| mysql_users                                        |
| proxysql_servers                                   |
| restapi_routes                                     |
| runtime_checksums_values                           |
| runtime_global_variables                           |
| runtime_mysql_aws_aurora_hostgroups                |
| runtime_mysql_firewall_whitelist_rules             |
| runtime_mysql_firewall_whitelist_sqli_fingerprints |
| runtime_mysql_firewall_whitelist_users             |
| runtime_mysql_galera_hostgroups                    |
| runtime_mysql_group_replication_hostgroups         |
| runtime_mysql_query_rules                          |
| runtime_mysql_query_rules_fast_routing             |
| runtime_mysql_replication_hostgroups               |
| runtime_mysql_servers                              |
| runtime_mysql_users                                |
| runtime_proxysql_servers                           |
| runtime_restapi_routes                             |
| runtime_scheduler                                  |
| scheduler                                          |
+----------------------------------------------------+
--表名以runtiem_开头的表示proxySQL服务中当前运行的配置内容,不能直接修改,不带runtime是mem相关的配置
02 ProxySQL管理接口的多层配置关系

第一层:RUNTIME:

代表proxySQL当前正在使用的配置,无法直接修改此配置,必须要从下一层(MEM层)load加载进来;

第二层:MEMORY(主要修改的配置表)

memory层上面连接runtime层,下面连接disk持久化存储层;

在这层可以在线操作ProxySQL配置,随意进行修改,不会影响生产环境,确认正常之后再加载到runtime和持久化保存到磁盘上;

具体修改操作方法为:insert、update、delete、select;

第三层:DISK/CFG FILE

持久化配置信息,重启时可以从磁盘快速加载回来;

sql 复制代码
# 01 user相关配置
LOAD MYSQL USERS TO RUNTIME;
-- MEM加载到runtime
SAVE MYSQL USERS TO MEMORY;
-- RUNTIME保存至MEM
LOAD MYSQL USERS FROM DISK;
-- DISK加载到MEM
SAVE MYSQL USERS TO DISK;
-- MEM保存至DISK
LOAD MYSQL USERS FROM CONFIG
-- CFG加载到MEM

# 02 server相关配置
LOAD MYSQL SERVERS TO RUNTIME;
-- MEM加载到RUNTIME
SAVE MYSQL SERVERS TO MEMORY;
-- RUNTIME保存至MEM
LOAD MYSQL SERVERS FROM DISK;
-- DISK加载到MEM
SAVE MYSQL SERVERS TO DISK;
-- MEM保存至DISK
LOAD MYSQL SERVERS FROM CONFIG
-- CFG加载到MEM

# 03 MYSQL QUERY RULES相关配置
LOAD MYSQL QUERY RULES TO RUNTIME;
-- MEM加载到RUNTIME
SAVE MYSQL QUERY RULES TO MEMORY;
-- RUNTIME保存至MEM
LOAD MYSQL QUERY RULES FROM DISK;
-- DISK加载到MEM
SAVE MYSQL QUERY RULES TO DISK;
-- MEM保存至DISK
LOAD MYSQL QUERY RULES FROM CONFIG
-- CFG加载到MEM

# 03 MYSQL VARIABLES相关配置
LOAD MYSQL VARIABLES TO RUNTIME;
-- MEM加载到RUNTIME
SAVE MYSQL VARIABLES TO MEMORY;
-- RUNTIME保存至MEM
LOAD MYSQL VARIABLES FROM DISK;
-- DISK加载到MEM
SAVE MYSQL VARIABLES TO DISK;
-- MEM保存至DISK
LOAD MYSQL VARIABLES FROM CONFIG
-- CFG加载到MEM
3. ProxySQL基于SQL语句进行读写分离实践配置

读写分离配置过程:

步骤 操作说明 涉及数据表信息 涉及操作信息
01 设置从库只读模式 read_only=1
02 添加主机组信息 mysql_replication_hostgroups
03 添加主机组节点信息 mysql_servers
04 添加用户信息(监控用户 应用用户) global_variables mysql_users
05 添加读写分离规则 mysql_query_rules
01 mysql_replication_hostgroup 配置读写组编号

proxySQL会根据server的read only的取值将服务器进行分组:

  • read_only=0的server,即master会被分到编号为10的写组;
  • read_only=1的server,即slave会被分到编号为20的读组;(所以需要将从库设置:set global read_only=1
sh 复制代码
db03 [(none)]>insert into mysql_replication_hostgroups(writer_hostgroup,reader_hostgroup,comment) values(10,20,'proxy');

db03 [(none)]>save mysql servers to disk;

db03 [(none)]>load mysql servers to runtime;

db03 [(none)]>select * from mysql_replication_hostgroups\G
*************************** 1. row ***************************
writer_hostgroup: 10
reader_hostgroup: 20
      check_type: read_only
         comment: proxy
1 row in set (0.00 sec)
02 添加主机到ProxySQL
sh 复制代码
db03 [(none)]>insert into mysql_servers(hostgroup_id,hostname,port) values (10,'10.0.0.50',3306);
db03 [(none)]>insert into mysql_servers(hostgroup_id,hostname,port) values (20,'10.0.0.52',3306);
db03 [(none)]>insert into mysql_servers(hostgroup_id,hostname,port) values (20,'10.0.0.53',3306);

db03 [(none)]>save mysql servers to disk;
db03 [(none)]>load mysql servers to runtime;
db03 [(none)]>select * from mysql_servers\G;
03 创建监控用户,并开启监控

利用监控用户对后端节点的运行情况进行监控数据同步,一旦后端节点出现数据同步异常,就不要再向故障节点发送相应业务请求;

sh 复制代码
# 主库创建监控用户
db01 [(none)]>create user monitor@'%' identified with mysql_native_password by '12366';
db01 [(none)]>grant replication client on *.* to monitor@'%';

# 在db03的proxysql中修改variables表配置信息方法一
db03 [(none)]>set mysql-monitor_username='monitor';
db03 [(none)]>set mysql-monitor_password='12366';

#方法二
db03 [(none)]>update global_variables set variable_value='monitor' where variable_name='mysql-monitor_username';
db03 [(none)]>update global_variables set variable_value='12366' where variable_name='mysql-monitor_password';

db03 [(none)]>load mysql variables to runtime;
db03 [(none)]>save mysql variables to disk;

# 检查核实配置信息
db03 [(none)]>select @@mysql-monitor_username;
+--------------------------+
| @@mysql-monitor_username |
+--------------------------+
| monitor                  |
+--------------------------+
1 row in set (0.00 sec)

db03 [(none)]>select @@mysql-monitor_password;
+--------------------------+
| @@mysql-monitor_password |
+--------------------------+
| 12366                    |
+--------------------------+
1 row in set (0.00 sec)


# 查询监控日志信息
db03 [(none)]>select * from mysql_server_connect_log;                                 
-- 检查确认所有节点的连接访问情况

db03 [(none)]>select * from mysql_server_ping_log;
-- 检查确认所有节点的网络连通情况

db03 [(none)]>select * from mysql_server_read_only_log;
-- 检查确认所有节点的只读状态信息(获取主库或从库主机信息)

db03 [(none)]>select * from mysql_server_replication_lag_log;
-- 检查确认所有节点的主从延时情况
04 创建应用用户信息

创建数据库应用用户信息,利用应用用户,可以使proxySQL进行数据库节点的操作管理;

sh 复制代码
# 主库创建应用用户
db01 [(none)]>create user root@'%' identified with mysql_native_password by '12366';

db01 [(none)]>grant all on *.* to root@'%';

# 在proxysql中添加数据库节点的管理用户信息
db03 [(none)]>insert into mysql_users(username,password,default_hostgroup) values('root','12366',10);
db03 [(none)]>load mysql users to runtime;
db03 [(none)]>save mysql users to disk;

# 早期版本,需要开启事务的持续化(忽略)
update mysql_users set transaction_persistent=1 where username='root';
load mysql users to runtime;
save mysql users to disk;
-- 事务路由分配持续性,同一个事务的语句不会被分配到不同的组
05 实用的读写规则配置
sh 复制代码
    db03 [(none)]> insert into mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply) values (1,1,'^select.*for update$',10,1);
Query OK, 1 row affected (0.00 sec)

db03 [(none)]>insert into mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply) values (2,1,'^select',20,1);
Query OK, 1 row affected (0.00 sec)

db03 [(none)]>load mysql query rules to runtime;
Query OK, 0 rows affected (0.00 sec)

db03 [(none)]>save mysql query rules to disk;
Query OK, 0 rows affected (0.01 sec)
-- 其余数据库操作语句信息,默认路由放置到主节点进行执行

说明:select ... for update规则的rule_id必须要小于普通的select规则的rule_id,proxySQL是根据rule_id的顺序进行规则匹配的;
06 测试读写分离效果
sh 复制代码
root@db03 ~]# mysql -uroot -p12366 -P6033 -h127.0.0.1 -e "begin;select @@server_id;commit"
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------------+
| @@server_id |
+-------------+
|          51 |
+-------------+
-- 非查询操作走的是主节点
[root@db03 ~]# mysql -uroot -p12366 -P6033 -h127.0.0.1 -e "select @@server_id;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------------+
| @@server_id |
+-------------+
|          52 |
+-------------+
[root@db03 ~]# mysql -uroot -p12366 -P6033 -h127.0.0.1 -e "select @@server_id;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------------+
| @@server_id |
+-------------+
|          53 |
+-------------+
-- 查询操作走的是从节点

db03 [(none)]>select * from stats_mysql_query_digest\G
-- 这个表对于分析SQL语句至关重要,是分析语句性能、定制路由规则指标的最主要来源
4. 读写分离架构软件配置扩展
01 基于端口进行读写分离路由
sh 复制代码
# 修改proxySQL监听SQL流量的端口号,监听多端口信息
db03 [(none)]> set mysql-interfaces='0.0.0.0:6033;0.0.0.0:6034'

# 使监听端口配置信息生效
db03 [(none)]> save mysql variables to disk;
[root@db03 ~]# systemctl restart proxysql

# 设定相应读写分离路由规则
db03 [(none)]> delete from mysql_query_rules;
-- 为了测试效果,先清空已有规则信息
db03 [(none)]> insert into mysql_query_rules(rule_id,active,proxy_port,destination_hostgroup,apply) values(1,1,6033,10,1),(2,1,6034,20,1);

db03 [(none)]> load mysql query rules to runtime;
db03 [(none)]> save mysql query rules to disk;
-- 除了基于端口进行分离,还可以基于监听地址(修改字段proxy_addr即可),也可以基于客户端地址(修改字段client_addr字段即可);
02 基于用户进行读写分离路由
sql 复制代码
db03 [(none)]>  insert into mysql_users(username,password,default_hostgroup) values ('write','123',10),('reader','123',20);
db03 [(none)]>  load mysql users to runtime;
db03 [(none)]>  save mysql users to disk;

db03 [(none)]>  delete from mysql_query_rules;
-- 为了测试效果,先清空已有规则信息
db03 [(none)]>  insert into mysql_query_rules(rule_id,active,username,destination_hostgroup,apply) values (1,1,'write',10,1),(2,1,'reader',20,1);
db03 [(none)]>  load mysql users to runtime;
db03 [(none)]>  save mysql users to disk;

四、总结

ProxySQL作为一款功能强大的MySQL代理中间件,通过智能的查询路由机制实现了高效的读写分离架构。其主要价值体现在:

  • 负载均衡:将读操作分发到多个从节点,显著降低主库压力
  • 高可用性:结合监控机制实现故障自动检测和切换
  • 灵活配置:支持基于SQL模式、端口、用户等多种路由策略
  • 动态管理:支持配置热加载,无需重启服务即可生效变更
相关推荐
人工干智能1 小时前
LlamaIndex:使用向量数据库进行检索,loaded_query_engine.query(“..........?“)
数据库·llm
咸鱼翻身小阿橙2 小时前
SQL上半部分
服务器·数据库·sql
Elastic 中国社区官方博客2 小时前
Elasticsearch:监控 LLM 推理和 Agent Builder 使用 OpenRouter
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
知识分享小能手2 小时前
Oracle 19c入门学习教程,从入门到精通,Oracle 数据表对象 —— 语法知识点详解与案例实践(10)
数据库·学习·oracle
heze092 小时前
sqli-labs-Less-24
mysql·网络安全
Gobysec2 小时前
Goby 漏洞安全通告|GNU InetUtils Telnetd USER环境变量注入 权限绕过漏洞(CVE-2026-24061)
数据库·安全·gnu·漏洞分析·漏洞预警
wregjru2 小时前
【QT】2.QT 信号和槽
数据库
麦兜*2 小时前
SpringBoot Profile多环境配置详解,一套配置应对所有场景
java·数据库·spring boot
javajingling2 小时前
redis命令
数据库·redis·缓存