ProxySQL 代理Mysql实现读写分离

前提是你已经完成mysql 主从同步配置,参考:Docker mysql主从同步_docker mysql8主从同步跟随docker自启动无需配置-CSDN博客

1.启动一个proxysql

javascript 复制代码
docker run -d \
  --name proxysql \
  --network host \
  --restart=always \
  -e PROXYSQL_ADMIN_USERNAME=admin \
  -e PROXYSQL_ADMIN_PASSWORD=admin \
  proxysql/proxysql:latest

2.配置读写分离

javascript 复制代码
docker exec -it proxysql mysql -u admin -padmin -h 127.0.0.1 -P 6032

-- 1. 添加后端 MySQL 节点 端口按照你实际来
-- 主库
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (10, '127.0.0.1', 3306); 
-- 从库1
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (20, '127.0.0.1', 3307); 
-- 从库2
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (20, '127.0.0.1', 3308); 

-- 2. 创建应用用户(必须和你原来数据源配置的 MySQL 的账号一致)
INSERT INTO mysql_users(username, password, default_hostgroup) VALUES ('root', 'root', 10);

-- 3. 设置读写分离规则
INSERT INTO mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup, apply) VALUES (1, 1, '^SELECT.*', 20, 1);
INSERT INTO mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup, apply) VALUES (2, 1, '^SELECT.*FOR UPDATE', 10, 1);

-- 4. 加载并保存配置
LOAD MYSQL SERVERS TO RUNTIME;
LOAD MYSQL USERS TO RUNTIME;
LOAD MYSQL QUERY RULES TO RUNTIME;

SAVE MYSQL SERVERS TO DISK;
SAVE MYSQL USERS TO DISK;
SAVE MYSQL QUERY RULES TO DISK;

EXIT;

3.验证目标:

写操作(INSERT/UPDATE/CREATE 等)→ 走主库(3306)

读操作(SELECT)→ 走从库(3307 或 3308)

javascript 复制代码
# 1. 清空历史统计(可选,让结果更干净)
docker exec -it proxysql mysql -u admin -padmin -h 127.0.0.1 -P 6032 -e "SELECT * FROM stats_mysql_query_digest_reset;"

# 2. 执行一个读操作(比如 SELECT NOW())
docker exec -it proxysql mysql -u root -proot -h 127.0.0.1 -P 6033 -e "SELECT NOW();"

# 3. 执行一个写操作(比如建表)
docker exec -it proxysql mysql -u root -proot -h 127.0.0.1 -P 6033 -e "CREATE DATABASE IF NOT EXISTS test_verify;"

# 4. 查看统计结果
docker exec -it proxysql mysql -u admin -padmin -h 127.0.0.1 -P 6032 -e "
  SELECT 
    hostgroup, 
    digest_text AS query,
    count_star AS times
  FROM stats_mysql_query_digest;
  1. 验证成功后,修改springboot服务的数据源配置的IP 和端口,IP是proxysql所在的机器,端口是6033。 6032 是proxysql的管理端口;6033是 ProxySQL 的 MySQL 数据代理端口给应用程序、DBeaver、Navicat 等工具使用的。

至于账户和密码建议创建一个和原来直连Mysql使用的账户一样的,上面已经配置过了,这里再强调一遍,如果上面没有配置或者以后微服务的数据源修改账户,就需要下面一样添加一个

javascript 复制代码
docker exec -it proxysql mysql -u admin -padmin -h 127.0.0.1 -P 6032

-- 查看现有用户
SELECT * FROM mysql_users;

-- 如果没有,添加一个(用户名/密码需与后端 MySQL 一致!)
INSERT INTO mysql_users (username, password, default_hostgroup) 
VALUES ('root', 'root', 10);

-- 加载到运行时 & 持久化
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;

补充:解决ProxySQL 的单点故障问题

推荐方案:使用 Keepalived + VIP(虚拟 IP) 实现双机热备,这是最常用、轻量、高效的方案,适合中小规模系统。

javascript 复制代码
[DBeaver / App]
        ↓
   [VIP: 192.168.208.100]   ← 虚拟 IP(漂移 IP)
        ↓
┌─────────────┐    ┌─────────────┐
│ ProxySQL-1  │    │ ProxySQL-2  │
│ (192.168.208.11) │ (192.168.208.12) │
└─────────────┘    └─────────────┘
        ↓                   ↓
     [MySQL 主从集群(共享后端)]


正常时:VIP 在 ProxySQL-1 上,所有流量走它。
ProxySQL-1 挂了:VIP 自动漂移到 ProxySQL-2,服务不中断。
应用只连 VIP + 6033,完全无感知。

部署步骤(简要)
1. 准备两台服务器(或容器),安装相同版本的 ProxySQL

配置相同的 mysql_servers、mysql_users、mysql_query_rules

建议:配置同步脚本或使用配置管理工具(Ansible)保证一致性

2. 在两台机器上安装 Keepalived,对照自己的系统来安装

javascript 复制代码
cat /etc/os-release
javascript 复制代码
# Ubuntu/Debian
sudo apt install keepalived -y

# CentOS/RHEL
sudo yum install keepalived -y

# 补充
yum install -y procps-ng

验证pgrep 是否安装成功

3. 配置 Keepalived(主节点)

javascript 复制代码
# /etc/keepalived/keepalived.conf (ProxySQL-1)
vrrp_script chk_proxysql {
    script "/usr/bin/pgrep proxysql"   # 检查 proxysql 进程
    interval 2
    weight -5
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0                     # 改为你的网卡名
    virtual_router_id 51
    priority 100                       # 主 > 备
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        192.168.208.100/24            # VIP
    }
    track_script {
        chk_proxysql
    }
}

4. 配置 Keepalived(备节点)

javascript 复制代码
# /etc/keepalived/keepalived.conf (ProxySQL-2)
vrrp_script chk_proxysql {
    script "/usr/bin/pgrep proxysql"
    interval 2
    weight -5
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 90                        # 比主低
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        192.168.208.100/24
    }
    track_script {
        chk_proxysql
    }
}

5. 启动 Keepalived

javascript 复制代码
sudo systemctl enable --now keepalived

6. DBeaver 连接 VIP

Host: 192.168.208.100

Port: 6033

用户密码不变

现在即使一台 ProxySQL 挂了,VIP 会自动漂移,连接短暂中断后自动恢复(通常 < 3 秒)。

7.验证

准备工作(开两个窗口)

窗口 A(连着 131 主机):输入 watch -n 1 'ip addr show ens33 | grep 200'

作用:实时监控 VIP 还在不在 131 上。

窗口 B(连着 110 备机):输入 watch -n 1 'ip addr show ens33 | grep 200'

作用:实时监控 VIP 有没有飘到 110 上。

在 131 主机上执行:

docker stop keepalived

相关推荐
Thanks_ks1 天前
告别主从延迟:MySQL 同步瓶颈的全链路诊断与架构兜底实践
mysql·数据库架构·读写分离·性能调优·故障诊断·主从延迟·mts 并行复制
J超会运5 天前
OpenEuler MySQL主从复制+MyCat读写分离实战
mysql·读写分离·主从复制
散修-小胖子2 个月前
ProxySQL编译报错
mysql·proxysql
栗子叶3 个月前
阅读MySQL实战45讲专栏总结
数据库·mysql·innodb·主从同步·数据库原理
栗子叶3 个月前
深入理解 MySQL 半同步复制:AFTER_SYNC 为何能避免主从同步数据丢失?
数据库·mysql·adb·高可用·主从同步
a2155833204 个月前
Oracle 11g ADG 主从复制配置手册(Windows 环境)
windows·主从同步·oracle11g
奥尔特星云大使6 个月前
mysql读写分离中间件Atlas安装部署及使用
数据库·mysql·中间件·读写分离·atlas
奥尔特星云大使6 个月前
mysql读写分离中间件——Atlas详解
数据库·mysql·中间件·dba·读写分离
奥尔特星云大使6 个月前
读写分离中间件简介
数据库·mysql·中间件·读写分离