当前位置:首页 > 问答 > 正文

用keepalived来搞定MySQL高可用,避免单点故障那些事儿

主要综合自网络技术社区如CSDN、博客园等常见的技术分享文章,以及Keepalived官方文档的核心思想,以通俗化语言呈现)

咱们先来想一个场景,你有一个网站,这个网站的所有用户数据、订单数据都放在一个MySQL数据库里,这个数据库就运行在一台服务器上,平常日子一切都好,但万一这台服务器突然出问题了怎么办?比如硬盘坏了、断电了、或者网络抽风了,这下可糟了,数据库一挂,网站就打不开,用户没法下单,损失可就大了,这个“一台服务器坏了就全盘崩溃”的情况,就是所谓的“单点故障”。

那怎么解决呢?很自然的一个想法就是:备份一个呗,咱们弄两台服务器,都装上MySQL,一台主用,一台备用,主用的这台我们叫它“主库”,负责处理所有的读写请求;备用这台叫它“备库”,实时地从主库那里同步数据,保持数据一致,这样,一旦主库挂了,我们赶紧把备库推上去接管工作,网站就能继续运行了,这个“备库顶上去”的过程,高可用”要实现的核心目标。

用keepalived来搞定MySQL高可用,避免单点故障那些事儿

那么问题来了,怎么让这个“顶上去”的过程自动、快速、对用户无感知呢?总不能老是让运维人员24小时盯着,一发现问题就手动去切换吧?这时候,Keepalived这个工具就派上用场了。

你可以把Keepalived理解成一个非常忠诚、永不疲倦的“哨兵”或者“选举主持人”,它的核心工作就是管理一个“虚拟IP地址”(简称VIP),这个VIP不是一个真实的物理网卡上的地址,而是由Keepalived软件虚拟出来的一个IP,我们的网站程序不直接连接主库或者备库的真实IP,而是连接这个VIP。

我们把Keepalived分别安装在那台主库服务器和备库服务器上,让它们组成一个“小组”,这个小组内部会通过一种心跳机制(就是不断地互相发消息说“我还活着”)来检查对方的健康状况。

用keepalived来搞定MySQL高可用,避免单点故障那些事儿

正常情况下,哨兵(Keepalived)会通过一个简单的选举机制,让主库服务器赢得这个VIP,这个VIP就“飘”到了主库服务器上,所有来自网站的数据库连接请求,通过这个VIP,就自然而然地被引导到了主库上。

关键的部分来了:哨兵(Keepalived)会持续不断地检查主库的健康状态,它检查的方式可以很简单,比如周期性地执行一个我们预设的脚本,这个脚本的任务就是检查MySQL服务进程是不是还在运行、能不能执行一条简单的SQL查询(比如SELECT 1),只要这个脚本返回“成功”,哨兵就认为主库是健康的。

一旦主库真的出问题了(比如MySQL进程崩溃了),我们预设的那个健康检查脚本就会执行失败,这时,在主库服务器上运行的Keepalived哨兵就会意识到“我这边不行了”,它会主动放弃对VIP的持有,而在备库服务器上的那个一直在旁边观望的哨兵,发现主库哨兵没了心跳或者主库主动放弃VIP后,它会立刻宣布:“现在由我来接管!”它就会把那个VIP抢过来,绑定到自己的网卡上。

用keepalived来搞定MySQL高可用,避免单点故障那些事儿

这个过程非常快,通常一秒之内就能完成,对于网站程序来说,它感知到的可能就是数据库连接短暂中断了一下,然后马上又恢复了,因为它始终连接的是那个VIP,而VIP已经从故障的主库“飘移”到了健康的备库上,这样,备库就升级成了新的主库,开始提供服务,避免了业务长时间中断。

这里面还有一些细节需要考虑,原来那个主库修好之后,它是直接加回来作为新的备库呢,还是让它重新当主库?这涉及到主从切换的策略问题,Keepalived可以配置成不同的模式,一种常见的做法是,当原主库恢复后,让它作为备库重新加入,新的主库(由原备库升级而来)继续工作,这样可以避免数据在切换中混乱,这也就是所谓的“不抢占”模式。

为了避免“脑裂”情况(就是两个哨兵都认为自己是主库,导致VIP在两边同时出现,数据写乱),Keepalived的机制确保了在同一时间,只有一个节点能持有VIP。

用Keepalived来实现MySQL的高可用,核心思路就是:用一个虚拟IP(VIP)作为数据库的统一入口,由Keepalived这个“哨兵”根据MySQL的实际健康状况,动态地将VIP分配给健康的主库节点,从而实现故障时的自动、快速切换。 这种方法配置起来相对直观,能有效解决MySQL的单点故障问题,保证业务的连续性。

需要注意的是,这只是实现高可用的一种常见方案,它保证了服务的可用性,但通常需要配合MySQL的主从复制(Replication)来保证数据的一致性,也就是说,备库必须实时地从主库同步数据,才能在切换后提供准确的服务。