如何实现高可用性负载均衡的MySQL?,有哪些方案?
- 前端开发
- 2026-07-26
- 6
高可用性负载均衡的MySQL架构,核心是通过多节点冗余、故障自动切换和流量分发,确保数据库服务在故障时仍能持续读写,这是保障线上业务稳定性的基石。
什么样的MySQL架构才算真高可用?
很多朋友以为给MySQL配个主从复制就万事大吉了,但现实很残酷,真正的高可用,不是看你备份了几份数据,而是看当一台机器挂了,你的业务还能不能正常干活,用户甚至感知不到后端出过问题。
业内专家指出,一个生产级的高可用MySQL方案,必须具备三个核心能力:故障自动检测、秒级切换、读写流量无缝分发,缺一个,你都得在半夜爬起来手动修数据库。
对于大多数中小团队来说,讨论“高可用性负载均衡的mysql”时,最关心的其实是:怎么用最低的成本,搭出一个能扛住单点故障的集群? 这里要区分两个概念:高可用(HA)侧重故障切换,负载均衡侧重流量分发,但在实际部署中,它们往往是一体两面。
高可用和负载均衡,到底谁是谁的爹?
简单说,负载均衡是高可用的“前置条件”,没有负载均衡,你挂了一台主库,业务流量还是会往死里打;没有高可用,负载均衡发现后端节点挂了,也只会返回502。
常见的高可用架构有几种,但不是所有方案都适合用来做“高可用性负载均衡的mysql”,比如传统的主从+Sentinel,虽然能实现自动切换,但应用层面需要自己处理读写分离和故障感知,配置起来非常繁琐,尤其对于新手,容易在切换时出现数据不一致。
如何搭建一套能扛能打的keepalived+双主架构?
在实际生产里,Keepalived + 双主MySQL 是一个非常经典且性价比高的方案,特别适合预算有限又追求稳定的场景,这种架构能让两台MySQL互为主备,任意一台宕机,VIP(虚拟IP)自动漂移,业务端几乎无感知。
准备工作:两台机器,一条心跳线
你得准备两台配置差不多的服务器(物理机或云主机),操作系统建议CentOS 7或Ubuntu 20.04以上,它们之间最好有一条独立的千兆网卡做心跳检测,避免业务流量和心跳检测混在一起。
核心步骤一:配置双主复制
- 在两台机器上分别安装MySQL 8.0,并初始化数据目录。
- 修改my.cnf,每台机器的server-id必须不同,
- 节点1: server-id=1, log-bin=mysql-bin
- 节点2: server-id=2, log-bin=mysql-bin
- 分别在两台机器上创建用于复制的用户,并授权。
- 节点1锁表,查看File和Position;节点2执行CHANGE MASTER TO指向节点1,然后启动start slave。
- 反过来,节点1也执行CHANGE MASTER TO指向节点2。
- 检查show slave statusG,务必确认Slave_IO_Running和Slave_SQL_Running都是Yes。
核心步骤二:安装并配置Keepalived
- 在两台机器上安装Keepalived:yum install keepalived -y。
- 编辑/etc/keepalived/keepalived.conf,这是关键。
- 状态机:state MASTER(主)和state BACKUP(备)。
- 虚拟IP(VIP):定义一个业务IP,比如168.1.100,客户端连接这个IP就行。
- 优先级:主节点priority 100,备节点priority 90。
- 检测脚本:写一个脚本定期检查MySQL服务进程是否存活,如果MySQL挂了,Keepalived就自动降级,VIP漂移。
核心步骤三:如何防止脑裂?
脑裂是高可用架构里最头疼的问题,当两台服务器之间的心跳线断了,但MySQL都还活着,它们会同时接管VIP,导致数据写入冲突。

应对策略:
- 在Keepalived的脚本里加入仲裁机制,检测到MySQL故障后,不仅自己降级,还要尝试通过SSH远程关闭对端机器的Keepalived服务。
- 使用硬件仲裁,比如引入一个第三方的仲裁节点,但成本较高。
- 最稳妥的做法:配置强制广播,确保只有一台机器能持有VIP。
如何用ProxySQL实现生产级读写分离?
搭建好双主架构后,你会发现一个问题:应用端怎么连接? 如果直接连VIP,所有流量都打在主库上,从库基本闲置,无法分摊压力,这时候,“高可用性负载均衡的mysql”就缺不了ProxySQL这个中间件。
为什么不用传统的读写分离组件?
MySQL路由等旧工具虽然也能实现分离,但配置复杂,且对语法兼容性差。ProxySQL是近年来的主流选择,它支持100%的MySQL协议,配置灵活,而且支持在线配置修改,不用重启服务。
部署ProxySQL的实操姿势
- 在另一台机器(或部署在业务服务器上)安装ProxySQL,通过官方yum源或直接下载二进制包。
- 启动ProxySQL:systemctl start proxysql。
- 连接到ProxySQL的管理接口:mysql -u admin -p -h 127.0.0.1 -P 6032。
- 配置后端MySQL节点: INSERT INTO mysql_servers (hostgroup_id, hostname, port) VALUES (0, '192.168.1.10', 3306);
INSERT INTO mysql_servers (hostgroup_id, hostname, port) VALUES (0, '192.168.1.11', 3306);
INSERT INTO mysql_servers (hostgroup_id, hostname, port) VALUES (1, '192.168.1.12', 3306);
- hostgroup_id 0代表写组,1代表读组。
- 这里把双主都加入写组(0),但只让其中一个写;读组(1)则加入所有从节点或只读节点。
- 配置用户和监控: INSERT INTO mysql_users (username, password, default_hostgroup) VALUES ('app_user', 'app_pass', 0); UPDATE global_variables SET variable_value='monitor_user' WHERE variable_name='mysql-monitor_username'; LOAD MYSQL VARIABLES TO RUNTIME; SAVE MYSQL VARIABLES TO DISK;
- 配置读写分离规则: INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply) VALUES (1, 1, '^SELECT.FOR UPDATE', 0, 1);
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply) VALUES (2, 1, '^SELECT', 1, 1);
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
- 注意:SELECT ... FOR UPDATE 必须走写库,否则会出现数据不一致。
如何验证负载均衡效果?
连接ProxySQL的业务端口(默认6033),执行SELECT @@hostname,如果能看到不同的后端主机名交替出现,说明负载均衡已经生效,如果业务需要MySQL数据库高可用价格相对较低的方案,双主+ProxySQL的组合无疑是性价比之王,比商业数据库中间件便宜得多。
遇到故障时,这套架构如何自动恢复?
很多人担心,万一主库真的挂了,数据会不会丢?业务会不会中断?我们来模拟一下故障场景。

主库硬件宕机
- 故障检测:Keepalived的心跳检测脚本发现MySQL进程不存在,或者网络不通。
- VIP漂移:备库的Keepalived会接管VIP,并立即开始对外提供服务。
- 数据状态:如果双主是同步复制,备库数据是完整的,如果是异步复制,可能会有少量数据丢失,但大厂实践表明,绝大多数场景下,秒级数据丢失是可以接受的。
- 业务恢复:应用端连接的是VIP,或者通过ProxySQL连接,故障切换后,应用端几乎不需要修改连接字符串,除非你写死了IP。
ProxySQL自身故障
ProxySQL本身是一个无状态节点,可以部署多实例(比如两台机器各跑一个ProxySQL,前端再挂一个LVS或DNS轮询),如果一台ProxySQL挂了,另一台会接管所有流量,这就是高可用性负载均衡的mysql架构中常说的“全链路高可用”。
如何选择适合你的方案?
| 方案 | 适用场景 | 优势 | 代价 |
|---|---|---|---|
| Keepalived+双主 | 小型企业、预算有限 | 简单、稳定、成本低 | 脑裂风险、切换秒级延迟 |
| MHA+MySQL | 中等规模、追求自动化 | 故障切换快、数据一致性高 | 配置复杂、依赖Manager |
| ProxySQL+Galera | 高并发、强一致性 | 多点写入、无脑裂 | 对网络延迟敏感、维护成本高 |
| Orchestrator | 大型互联网公司、DBA团队 | 可视化、支持拓扑管理 | 学习曲线陡峭 |
如果你在北京做电商或者南京做游戏,需要高可用性负载均衡的mysql,建议优先考虑ProxySQL+双主或ProxySQL+Galera,前者适合MySQL数据库高可用价格敏感的团队,后者适合对数据一致性有极致要求的业务。
日常运维中,如何避免踩坑?
高可用性负载均衡的mysql配好之后,不是一劳永逸的,很多团队在线上出事故,往往是疏忽了以下细节。
监控报警要到位
- 检查延迟:seconds_behind_master 一旦超过阈值,必须报警。
- 检查复制状态:Slave_IO_Running和Slave_SQL_Running如果是No,说明复制中断,需要立刻处理。
- 检查ProxySQL连接池:如果ConnPool耗尽,新的连接会排队等待,导致接口超时。
定期做故障演练
- 每个月手动拔掉一台主库的网络线,看看VIP是否在预期时间内漂移,应用端是否有报错。
- 模拟ProxySQL超出内存的场景,看看它是否会自动熔断,拒绝新的连接。
- 每隔一段时间,在低峰期进行主从切换,确保DBA团队成员都能熟练操作。
版本升级要谨慎
- 不要在生产环境跑MySQL 8.0的早期版本,Bug较多,建议至少使用8.0.30以上。
- ProxySQL升级时,先备份配置文件,在测试环境验证读写分离规则是否有改变。
Q&A:高可用性负载均衡的mysql常见问题
问:我已经用了双主,为什么还需要ProxySQL?
答: 双主架构解决了故障切换的问题,但无法解决流量分发和读写分离,如果应用端直接连接双主,所有写操作都打到同一个IP,无法分摊压力,ProxySQL相当于一个智能路由器,将读请求均匀分发到多个从节点,写请求定向到主节点,这才是完整的“高可用性负载均衡的mysql”方案。
问:双主架构中,如果一台主库写入的数据没有同步到另一台,但VIP漂移到了没有数据的机器上,会发生什么?
答: 这是典型的数据不一致问题,如果业务不能容忍丢失数据,必须使用半同步复制(rpl_semi_sync_master)或者Galera集群,半同步复制能保证至少有一台从库收到binlog后,主库才返回commit成功,否则,如果使用了异步复制,且主库宕机时binlog尚未传送,切换到备库后,这部分数据会丢失,业务上可能表现为用户刚刚下单成功,但刷新后订单不见了。
问:我该选择VIP漂移还是DNS轮询来做负载均衡?
答: 对于MySQL高可用场景,强烈推荐VIP漂移,DNS轮询存在缓存问题,且无法做到秒级故障感知,你配置了A记录指向两台MySQL,但某台机器宕机了,客户端的DNS缓存可能还在几个小时,导致一大片用户无法连接,VIP漂移配合Keepalived,可以在几秒内完成切换,客户端感知最轻微。
