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模式、端口、用户等多种路由策略
  • 动态管理:支持配置热加载,无需重启服务即可生效变更
相关推荐
0xDevNull1 小时前
MySQL数据冷热分离详解
后端·mysql
科技小花2 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸2 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain2 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希2 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神3 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员3 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java3 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿3 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴3 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存