文章目录
-
- 一、基础概念与方案选型
-
- [1. 什么是MySQL负载均衡](#1. 什么是MySQL负载均衡)
- [2. 主流方案对比(生产首选ProxySQL/HAProxy)](#2. 主流方案对比(生产首选ProxySQL/HAProxy))
- 二、前置环境准备(通用,所有方案共用)
-
- 环境拓扑示例
- 步骤1:搭建MySQL主从复制(必须先做)
-
- [1.1 主库my.cnf配置](#1.1 主库my.cnf配置)
- [1.2 从库my.cnf(两台从库server-id分别2、3)](#1.2 从库my.cnf(两台从库server-id分别2、3))
- [1.3 创建ProxySQL监控/业务账号(所有MySQL节点执行)](#1.3 创建ProxySQL监控/业务账号(所有MySQL节点执行))
- [三、方案一:ProxySQL 读写分离+负载均衡(生产主流完整教程)](#三、方案一:ProxySQL 读写分离+负载均衡(生产主流完整教程))
-
- [1. 安装ProxySQL(CentOS7/8)](#1. 安装ProxySQL(CentOS7/8))
- [2. 注册后端MySQL节点(分写组、读组)](#2. 注册后端MySQL节点(分写组、读组))
- [3. 配置监控账号(自动健康检查)](#3. 配置监控账号(自动健康检查))
- [4. 配置自动读写分离路由规则(核心)](#4. 配置自动读写分离路由规则(核心))
- [5. 配置业务访问账号](#5. 配置业务访问账号)
- [6. 验证负载均衡与读写分离](#6. 验证负载均衡与读写分离)
-
- [6.1 应用连接代理](#6.1 应用连接代理)
- [6.2 验证读负载均衡(多次执行,交替返回两台从库hostname)](#6.2 验证读负载均衡(多次执行,交替返回两台从库hostname))
- [6.3 验证写路由(INSERT只会走到主库)](#6.3 验证写路由(INSERT只会走到主库))
- [6.4 查看路由统计(ProxySQL后台6032端口)](#6.4 查看路由统计(ProxySQL后台6032端口))
- [7. 高可用补充:双ProxySQL+Keepalived VIP](#7. 高可用补充:双ProxySQL+Keepalived VIP)
- [四、方案二:HAProxy 纯TCP读负载均衡(仅分发读流量)](#四、方案二:HAProxy 纯TCP读负载均衡(仅分发读流量))
-
- [1. 安装HAProxy](#1. 安装HAProxy)
- [2. 配置 /etc/haproxy/haproxy.cfg](#2. 配置 /etc/haproxy/haproxy.cfg)
- [3. 启动&验证](#3. 启动&验证)
- [五、方案三:MySQL Router(官方轻量,配套MGR/InnoDB Cluster)](#五、方案三:MySQL Router(官方轻量,配套MGR/InnoDB Cluster))
- 六、负载均衡核心运维要点
一、基础概念与方案选型
1. 什么是MySQL负载均衡
MySQL负载均衡核心目标:
- 读请求分摊:多从库分担查询压力,横向扩容读能力
- 读写分离:写统一走主库,读分发到从库
- 故障自动摘除:节点宕机不再转发流量
- 连接池复用:减少应用直连MySQL的连接数消耗
2. 主流方案对比(生产首选ProxySQL/HAProxy)
| 方案 | 层级 | 核心能力 | 适用场景 |
|---|---|---|---|
| HAProxy | 四层TCP代理 | 连接轮询、权重、健康检查,不解析SQL | 仅做读负载均衡、简单集群、低并发 |
| ProxySQL | SQL七层代理 | 自动读写分离、SQL规则路由、连接池、缓存 | 绝大多数业务(读多写少、无需改代码) |
| MySQL Router | 官方轻量代理 | 配合InnoDB Cluster/MGR,简单读写端口 | MySQL官方集群、小型业务 |
| LVS+Keepalived | 四层内核负载 | 性能最高,无流量损耗 | 超大流量、千级并发数据库集群 |
| 应用层分库 | 代码层面区分读写 | 零中间件,维护成本高 | 架构统一、研发可控团队 |
推荐新手/中小企业:ProxySQL,开箱即用读写分离,不用改业务代码。
二、前置环境准备(通用,所有方案共用)
环境拓扑示例
- Master主库:192.168.10.10:3306(写)
- Slave1从库:192.168.10.11:3306(读)
- Slave2从库:192.168.10.12:3306(读)
- ProxySQL代理:192.168.10.20(对外端口6033)
步骤1:搭建MySQL主从复制(必须先做)
1.1 主库my.cnf配置
ini
[mysqld]
server-id=1
log_bin=mysql-bin
binlog_format=ROW
gtid_mode=ON
enforce_gtid_consistency=ON
重启MySQL,创建复制账号:
sql
CREATE USER 'repl'@'%' IDENTIFIED BY 'Repl@123';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
SHOW MASTER STATUS; -- 记录File、Position
1.2 从库my.cnf(两台从库server-id分别2、3)
ini
[mysqld]
server-id=2
relay_log=relay-bin
read_only=ON
super_read_only=ON
gtid_mode=ON
enforce_gtid_consistency=ON
重启从库,配置同步:
sql
CHANGE MASTER TO
MASTER_HOST='192.168.10.10',
MASTER_USER='repl',
MASTER_PASSWORD='Repl@123',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=156;
START SLAVE;
SHOW SLAVE STATUS\G
# 校验:Slave_IO_Running=Yes,Slave_SQL_Running=Yes
1.3 创建ProxySQL监控/业务账号(所有MySQL节点执行)
sql
-- 监控账号(代理探测节点存活)
CREATE USER 'proxy_monitor'@'%' IDENTIFIED BY 'Monitor@123';
GRANT SELECT, REPLICATION CLIENT ON *.* TO 'proxy_monitor'@'%';
-- 业务访问账号(应用连接代理)
CREATE USER 'app_user'@'%' IDENTIFIED BY 'App@123';
GRANT ALL ON business.* TO 'app_user'@'%';
FLUSH PRIVILEGES;
三、方案一:ProxySQL 读写分离+负载均衡(生产主流完整教程)
1. 安装ProxySQL(CentOS7/8)
bash
yum install -y proxysql
systemctl start proxysql
systemctl enable proxysql
管理端口:6032(admin后台),业务端口默认6033(应用连接)
登录管理后台:
bash
mysql -uadmin -padmin -h127.0.0.1 -P6032
2. 注册后端MySQL节点(分写组、读组)
hostgroup规范:
- hostgroup_id=10:写组(仅主库)
- hostgroup_id=20:读组(所有从库,自动负载均衡)
sql
-- 清空原有配置
DELETE FROM mysql_servers;
-- 添加主库(写组)
INSERT INTO mysql_servers(hostgroup_id,hostname,port,weight,max_connections)
VALUES (10,'192.168.10.10',3306,1000,2000);
-- 添加两台从库(读组,权重相同轮询)
INSERT INTO mysql_servers(hostgroup_id,hostname,port,weight,max_connections)
VALUES
(20,'192.168.10.11',3306,100,2000),
(20,'192.168.10.12',3306,100,2000);
-- 加载到运行时、持久化磁盘
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
-- 查看节点
SELECT hostgroup_id,hostname,status,weight FROM mysql_servers;
3. 配置监控账号(自动健康检查)
sql
SET mysql_monitor_username='proxy_monitor';
SET mysql_monitor_password='Monitor@123';
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;
ProxySQL会每秒执行SELECT 1探测节点,宕机自动OFFLINE摘除。
4. 配置自动读写分离路由规则(核心)
规则优先级从上到下:
SELECT ... FOR UPDATE加锁查询强制走主库- 普通
SELECT走读组20(负载均衡分发) - INSERT/UPDATE/DELETE/DDL全部走写组10
sql
DELETE FROM mysql_query_rules;
-- 1. 行锁查询走主库
INSERT INTO mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply)
VALUES (1,1,'^SELECT .*FOR UPDATE$',10,0);
-- 2. 普通SELECT走从库读组
INSERT INTO mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply)
VALUES (2,1,'^SELECT',20,1);
-- 3. 其余所有SQL(增删改、建表)走主库
INSERT INTO mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply)
VALUES (3,1,'.',10,1);
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
5. 配置业务访问账号
sql
DELETE FROM mysql_users;
INSERT INTO mysql_users(username,password,default_hostgroup,transaction_persistent)
VALUES ('app_user','App@123',10,1);
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;
default_hostgroup=10:无匹配规则默认走主库,保障事务一致性。
6. 验证负载均衡与读写分离
6.1 应用连接代理
bash
mysql -uapp_user -pApp@123 -h192.168.10.20 -P6033
6.2 验证读负载均衡(多次执行,交替返回两台从库hostname)
sql
SELECT @@hostname;
6.3 验证写路由(INSERT只会走到主库)
sql
INSERT INTO test(name) VALUES('test');
6.4 查看路由统计(ProxySQL后台6032端口)
sql
SELECT hostgroup,sum_count,username FROM stats_mysql_query_digest;
7. 高可用补充:双ProxySQL+Keepalived VIP
两台ProxySQL部署Keepalived,对外统一虚拟IP,避免代理单点故障。
四、方案二:HAProxy 纯TCP读负载均衡(仅分发读流量)
适用场景:仅需要分摊读请求,不需要自动SQL读写分离,业务代码手动区分读写地址。
1. 安装HAProxy
bash
yum install haproxy -y
2. 配置 /etc/haproxy/haproxy.cfg
ini
global
log /dev/log local0
daemon
defaults
mode tcp
timeout connect 5s
timeout client 30s
timeout server 30s
# 前端监听3307,对外读端口
frontend mysql-read
bind 0.0.0.0:3307
default_backend slave_pool
# 后端从库集群,轮询负载均衡
backend slave_pool
mode tcp
balance roundrobin
server slave1 192.168.10.11:3306 check inter 2000 rise 2 fall 3
server slave2 192.168.10.12:3306 check inter 2000 rise 2 fall 3
# 监控页面
listen stats
bind 0.0.0.0:8080
stats enable
stats auth admin:123456
3. 启动&验证
bash
systemctl start haproxy
# 连接读均衡端口
mysql -uapp_user -pApp@123 -h192.168.10.20 -P3307
浏览器访问 http://代理IP:8080 查看节点在线状态。
五、方案三:MySQL Router(官方轻量,配套MGR/InnoDB Cluster)
- 安装mysql-router
- bootstrap自动发现集群
bash
mysqlrouter --bootstrap root@192.168.10.10:3306 --user=mysqlrouter
- 自动生成两个端口:
- 6446:读写端口(主库)
- 6447:只读端口(从库负载均衡)
业务区分端口连接即可,无需SQL解析。
六、负载均衡核心运维要点
1. 负载均衡调度算法
roundrobin:轮询,服务器性能均等weight:权重,高配机器分配更多请求leastconn:最少连接,适合长查询业务runtime weight:ProxySQL支持动态调整从库权重
2. 避坑关键点
- 主从延迟:实时报表、强一致性查询必须走主库,不要分配到从库
- SELECT ... FOR UPDATE:行锁查询禁止分发从库,否则数据不一致
- 事务边界:事务内所有SQL必须统一路由同一节点
- 健康检查间隔:ProxySQL默认1000ms,HAProxy推荐2000ms
- 连接数限制:proxy层控制max_connections,防止打满MySQL连接
3. 故障排查命令
ProxySQL
sql
-- 查看节点状态
SELECT hostname,status FROM mysql_servers;
-- 查看失败探测
SELECT * FROM monitor_mysql_servers;
-- SQL路由统计
SELECT digest_text,hostgroup,sum_count FROM stats_mysql_query_digest ORDER BY sum_count DESC;
HAProxy
bash
# 查看后端状态
echo "show servers state" | socat stdio /var/lib/haproxy/stats