MySQL 高可用集群 - 双主双活 - mysql+keepalived
本文基于 CentOS 7 系统环境进行部署测试,旨在通过 MySQL 原生主从复制功能结合 Keepalived 实现双主双活的高可用架构。
一、背景与方案
痛点场景: 在应用开发中,数据库连接信息往往硬编码在配置里。一旦主库(如 mysql-1)发生故障,运维人员需要手动停止服务、修改连接指向备用库(mysql-2)、再重启服务。这个过程不仅繁琐,还会导致业务中断,故障恢复时间较长,严重时可能引发灾难性后果。
解决方案: 采用 MySQL 双主互备模式配合 Keepalived 实现 VIP 漂移。两台 MySQL 服务器互为 Master 和 Slave,数据双向同步。Keepalived 通过虚拟一个 VIP(例如 mysql-3),代理后端数据库服务。当主节点宕机时,VIP 会自动漂移到备用节点,无需人工干预修改应用配置,实现业务无感知的故障切换。
二、环境准备
需要准备两台 CentOS 7 Linux 服务器:
- 节点 1 (mysql-1):192.168.1.128
- 节点 2 (mysql-2):192.168.1.129
软件版本建议:
- MySQL:5.7.36 (tar.gz)
- Keepalived:2.2.7 (tar.gz)
三、安装 MySQL
1. 基础安装
在两台服务器上分别按照标准流程安装 MySQL 5.7。
2. 配置文件调整
修改 mysql-1 (192.168.1.128) 的 /etc/my.cnf:
[client]
port=3306
socket=/opt/mysql/5.7.36/log/mysql.sock
default-character-set=utf8
[mysqld]
port=3306
basedir=/opt/mysql/5.7.36/
datadir=/opt/mysql/5.7.36/data
socket=/opt/mysql/5.7.36/log/mysql.sock
log-error=/opt/mysql/5.7.36/log/mysql.log
pid-file=/opt/mysql/5.7.36/log/mysql.pid
# 主从同步配置
server-id=1
log-bin=mysql-bin
binlog_do_db=test_db
binlog_format=row
character-set-server=utf8
!includedir /etc/my.cnf.d
修改 mysql-2 (192.168.1.129) 的 /etc/my.cnf,主要区别在于 server-id 设为 2:
...
server-id=2
...
3. 启动服务
重启两台服务器的 MySQL 服务:
systemctl stop mysqld
systemctl start mysqld
四、配置双主双从同步
1. 在 mysql-1 上创建同步账号并查看状态
grant replication slave on *.* to 'slavebak'@'%' identified by 'slavebak';
flush privileges;
show master status;
记录输出的 File 和 Position 值。
2. 在 mysql-2 上配置指向 mysql-1
change master to
master_host='192.168.1.128',
master_port=3306,
master_user='slavebak',
master_password='slavebak',
master_log_file='mysql-bin.000002',
master_log_pos=1287;
start slave;
检查状态确保 Slave_IO_Running 和 Slave_SQL_Running 均为 Yes。
3. 在 mysql-2 上创建同步账号并查看状态
重复步骤 1,记录新的 File 和 Position 值。
4. 在 mysql-1 上配置指向 mysql-2
change master to
master_host='192.168.1.129',
master_port=3306,
master_user='slavebak',
master_password='slavebak',
master_log_file='mysql-bin.000002',
master_log_pos=848;
start slave;
同样检查状态确保同步正常。
至此,双主双从的数据同步链路已打通。
五、数据同步测试
- 写入测试:在 mysql-1 创建
test_db库及t_test表,插入一条数据(id=1, name='zhangsan')。 - 验证同步:登录 mysql-2,确认
test_db库和表已存在,且数据已同步。随后在 mysql-2 插入第二条数据(id=2, name='lisi')。 - 回查:再次登录 mysql-1,查询
t_test表,应能看到两条数据。这证明双向同步工作正常。
六、安装与配置 Keepalived
1. 编译安装
在两台服务器上执行以下操作:
yum -y install gcc openssl-devel popt-devel psmisc
wget https://www.keepalived.org/software/keepalived-2.2.7.tar.gz
tar -zxvf keepalived-2.2.7.tar.gz
cd keepalived-2.2.7
./configure --prefix=/opt/keepalived-2.2.7
make && make install
2. 文件部署
将二进制文件和配置文件复制到系统目录:
mkdir /etc/keepalived
cp etc/keepalived/keepalived.conf.sample /etc/keepalived/keepalived.conf
cp keepalived/etc/init.d/keepalived /etc/init.d/
cp keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp sbin/keepalived /usr/sbin/
3. 编写健康检查脚本
创建 /etc/keepalived/shutdown.sh,用于检测 MySQL 异常时停止 Keepalived,触发 VIP 漂移:
#!/bin/bash
killall keepalived
赋予执行权限:chmod +x /etc/keepalived/shutdown.sh
4. 配置 Keepalived
获取本机网卡名称(例如 ens33),然后编辑 /etc/keepalived/keepalived.conf。
mysql-1 配置示例:
global_defs {
router_id LVS_MASTER
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.130
}
}
virtual_server 192.168.1.130 3306 {
delay_loop 6
lb_algo rr
lb_kind NAT
protocol TCP
real_server 192.168.1.128 3306 {
notify_down /etc/keepalived/shutdown.sh
TCP_CHECK {
connect_ip 192.168.1.128
connect_port 3306
connect_timeout 3
}
}
}
mysql-2 配置示例:
主要区别在于 state BACKUP,priority 90,以及 real_server IP 指向 192.168.1.129。
5. 启动服务
systemctl enable keepalived
systemctl start keepalived
systemctl status keepalived
七、高可用整体测试
- 初始连接:使用客户端连接 VIP
192.168.1.130,确认能正常访问数据库。 - 模拟故障:手动停止
mysql-1上的 MySQL 服务 (systemctl stop mysqld)。 - 观察漂移:Keepalived 检测到端口不可达后,会执行
shutdown.sh脚本,自身退出,VIP 自动漂移到mysql-2。 - 验证切换:再次连接 VIP,此时流量由
mysql-2承载。在 VIP 上插入新数据,并在mysql-2本地验证数据存在,同时检查mysql-1重启后数据是否同步回来。
若 VIP 未漂移,请检查同网段内 virtual_router_id 是否冲突,可使用 tcpdump 抓包排查 VRRP 协议报文。
通过以上步骤,我们完成了 MySQL 双主双活架构与 Keepalived 高可用方案的完整部署与验证。


