当前位置:首页 > 前端开发 > 正文

如何实现高可用性负载均衡的MySQL?,有哪些方案?

高可用性负载均衡的MySQL架构,核心是通过多节点冗余、故障自动切换和流量分发,确保数据库服务在故障时仍能持续读写,这是保障线上业务稳定性的基石。

什么样的MySQL架构才算真高可用?

很多朋友以为给MySQL配个主从复制就万事大吉了,但现实很残酷,真正的高可用,不是看你备份了几份数据,而是看当一台机器挂了,你的业务还能不能正常干活,用户甚至感知不到后端出过问题。

业内专家指出,一个生产级的高可用MySQL方案,必须具备三个核心能力:故障自动检测秒级切换读写流量无缝分发,缺一个,你都得在半夜爬起来手动修数据库。

对于大多数中小团队来说,讨论“高可用性负载均衡的mysql”时,最关心的其实是:怎么用最低的成本,搭出一个能扛住单点故障的集群? 这里要区分两个概念:高可用(HA)侧重故障切换,负载均衡侧重流量分发,但在实际部署中,它们往往是一体两面。

高可用和负载均衡,到底谁是谁的爹?

简单说,负载均衡是高可用的“前置条件”,没有负载均衡,你挂了一台主库,业务流量还是会往死里打;没有高可用,负载均衡发现后端节点挂了,也只会返回502。

常见的高可用架构有几种,但不是所有方案都适合用来做“高可用性负载均衡的mysql”,比如传统的主从+Sentinel,虽然能实现自动切换,但应用层面需要自己处理读写分离和故障感知,配置起来非常繁琐,尤其对于新手,容易在切换时出现数据不一致。

如何搭建一套能扛能打的keepalived+双主架构?

在实际生产里,Keepalived + 双主MySQL 是一个非常经典且性价比高的方案,特别适合预算有限又追求稳定的场景,这种架构能让两台MySQL互为主备,任意一台宕机,VIP(虚拟IP)自动漂移,业务端几乎无感知。

准备工作:两台机器,一条心跳线

你得准备两台配置差不多的服务器(物理机或云主机),操作系统建议CentOS 7或Ubuntu 20.04以上,它们之间最好有一条独立的千兆网卡做心跳检测,避免业务流量和心跳检测混在一起。

核心步骤一:配置双主复制

  1. 两台机器上分别安装MySQL 8.0,并初始化数据目录。
  2. 修改my.cnf,每台机器的server-id必须不同,
    • 节点1: server-id=1, log-bin=mysql-bin
    • 节点2: server-id=2, log-bin=mysql-bin
  3. 分别在两台机器上创建用于复制的用户,并授权。
  4. 节点1锁表,查看File和Position;节点2执行CHANGE MASTER TO指向节点1,然后启动start slave。
  5. 反过来,节点1也执行CHANGE MASTER TO指向节点2。
  6. 检查show slave statusG,务必确认Slave_IO_Running和Slave_SQL_Running都是Yes。

核心步骤二:安装并配置Keepalived

  1. 在两台机器上安装Keepalived:yum install keepalived -y。
  2. 编辑/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,导致数据写入冲突。

如何实现高可用性负载均衡的MySQL?,有哪些方案? 第1张

应对策略:

  • 在Keepalived的脚本里加入仲裁机制,检测到MySQL故障后,不仅自己降级,还要尝试通过SSH远程关闭对端机器的Keepalived服务。
  • 使用硬件仲裁,比如引入一个第三方的仲裁节点,但成本较高。
  • 最稳妥的做法:配置强制广播,确保只有一台机器能持有VIP。

如何用ProxySQL实现生产级读写分离?

搭建好双主架构后,你会发现一个问题:应用端怎么连接? 如果直接连VIP,所有流量都打在主库上,从库基本闲置,无法分摊压力,这时候,“高可用性负载均衡的mysql”就缺不了ProxySQL这个中间件。

为什么不用传统的读写分离组件?

MySQL路由等旧工具虽然也能实现分离,但配置复杂,且对语法兼容性差。ProxySQL是近年来的主流选择,它支持100%的MySQL协议,配置灵活,而且支持在线配置修改,不用重启服务。

部署ProxySQL的实操姿势

  1. 在另一台机器(或部署在业务服务器上)安装ProxySQL,通过官方yum源或直接下载二进制包。
  2. 启动ProxySQL:systemctl start proxysql。
  3. 连接到ProxySQL的管理接口:mysql -u admin -p -h 127.0.0.1 -P 6032。
  4. 配置后端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)则加入所有从节点或只读节点。
  5. 配置用户和监控: 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;
  6. 配置读写分离规则: 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的组合无疑是性价比之王,比商业数据库中间件便宜得多。

遇到故障时,这套架构如何自动恢复?

很多人担心,万一主库真的挂了,数据会不会丢?业务会不会中断?我们来模拟一下故障场景。

如何实现高可用性负载均衡的MySQL?,有哪些方案? 第2张

主库硬件宕机

  1. 故障检测:Keepalived的心跳检测脚本发现MySQL进程不存在,或者网络不通。
  2. VIP漂移:备库的Keepalived会接管VIP,并立即开始对外提供服务。
  3. 数据状态:如果双主是同步复制,备库数据是完整的,如果是异步复制,可能会有少量数据丢失,但大厂实践表明,绝大多数场景下,秒级数据丢失是可以接受的
  4. 业务恢复:应用端连接的是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,可以在几秒内完成切换,客户端感知最轻微。

如何实现高可用性负载均衡的MySQL?,有哪些方案? 第3张

0