MySQL数据库(七)—— 基于主主复制与 Keepalived 非抢占模式的高可用方案
文章目录
- 前言
- 一、环境规划
- 1.1 节点信息
- 1.2 服务版本
- 1.3 搭建思路
- 1.4 基础环境配置
- 二、MySQL 主主复制配置
- 2.1 修改 MySQL 配置文件
- 2.1.1 Node1 (192.168.10.14) 配置
- 2.1.2 Node2 (192.168.10.15) 配置
- 2.2 创建复制账户和安全检查账户
- 2.3 配置双向同步
- 2.3.1 在 Node1 上配置到 Node2 的复制
- 2.3.2 在 Node2 上配置到 Node1 的复制
- 2.4 验证复制状态
- 三、Keepalived 非抢占模式配置
- 3.1 安装 Keepalived
- 3.2 配置 Keepalived
- 3.2.1 Node1 配置 (192.168.10.14)
- 3.2.2 Node2 配置 (192.168.10.15)
- 3.3 MySQL 健康检查脚本
- 3.4 启动 Keepalived 服务
- 3.5 验证 VIP 绑定
- 3.6 测试使用VIP连接MySQL
- 四、故障转移与恢复流程
- 4.1 故障转移(Node1 节点故障)
- 4.2 故障恢复(原主节点恢复)
- 4.3 强制切换回原主(可选操作)
- 五、方案优势与注意事项
- 5.1 方案优势
- 5.2 注意事项
- 总结
前言
在生产环境中,数据库高可用性是系统稳定运行的关键保障。MySQL 主从复制提供了数据冗余和读写分离的能力,但单点故障问题仍然存在。
本文将详细介绍通过 MySQL 主主复制 + Keepalived 实现高可用数据库集群的方案,使用 VIP(虚拟 IP)作为应用的统一访问入口,实现故障自动转移与恢复,并采用非抢占模式确保集群稳定性。
一、环境规划
1.1 节点信息
节点名称 | IP 地址 | 角色 | 服务组件 |
---|---|---|---|
Node1 | 192.168.10.14 | 初始主节点 | MySQL + Keepalived |
Node2 | 192.168.10.15 | 初始备节点 | MySQL + Keepalived |
VIP | 192.168.10.180 | 应用访问入口 | 虚拟 IP(由 Keepalived 管理) |
客户端 | 192.168.10.120 | 测试客户端 | MySQL |
+-------------------------------------------------------+
| 应用服务器 |
| |
| 访问: 192.168.10.180 |
+--------------------------|----------------------------+|| VIP: 192.168.10.180|+-----------------+------------------+| || |
+--------|---------+ +---------|--------+
| Node1 | | Node2 |
| IP: 192.168.10.14| | IP: 192.168.10.15|
| | | |
| MySQL (Master1) |<-------------->| MySQL (Master2) |
| Keepalived (MASTER) | Keepalived (BACKUP)|
| | | |
+------------------+ +-------------------+说明:
MySQL双向复制:Node1和Node2之间互相复制数据。
Keepalived:Node1初始为MASTER状态,持有VIP;Node2为BACKUP状态。
当Node1的MySQL服务失败,Keepalived会将VIP转移到Node2,同时应用服务器访问VIP的请求会被路由到Node2
1.2 服务版本
- 操作系统: CentOS 7.9
- MySQL: 5.7
- Keepalived: 1.3.5(yum 安装版本)
1.3 搭建思路
(1)安装 MySQL 数据库;
(2)配置 MySQL 互为主从;
(3)安装 keepalived 软件并配置故障转移;
(4)模拟 master 故障切换
(5)实现故障恢复
1.4 基础环境配置
# 关闭防火墙和增强功能
systemctl stop firewalld.service
setenforce 0
二、MySQL 主主复制配置
MySQL 主主复制实质上是双向的主从复制,两台服务器互为 Master 和 Slave。
MySQL的安装步骤可以参考:MySQL安装管理指南
2.1 修改 MySQL 配置文件
两台服务器均需进行以下配置,注意 server-id 和 auto_increment_offset 的区别:
2.1.1 Node1 (192.168.10.14) 配置
# /etc/my.cnf
[mysqld]
# 服务器唯一标识,Node1 设为 1,Node2 设为 2
server-id = 1# 开启二进制日志
log-bin = mysql-bin# 中继日志配置
relay-log = relay-log# 自增步长设为2,避免主键冲突
auto_increment_increment = 2# Node1 自增起始值为1
auto_increment_offset = 1# 行级复制,保证数据一致性
binlog_format = ROW# 开启 GTID
gtid_mode = ON
enforce_gtid_consistency = ON# 禁止 Slave 自动启动,需手动开启
skip_slave_start = 1# 可选:减少复制错误风险
log_slave_updates = ON
2.1.2 Node2 (192.168.10.15) 配置
# /etc/my.cnf
[mysqld]
server-id = 2
log-bin = mysql-bin
relay-log = relay-log
auto_increment_increment = 2
auto_increment_offset = 2 # Node2 自增起始值为2
binlog_format = ROW
gtid_mode = ON
enforce_gtid_consistency = ON
skip_slave_start = 1
log_slave_updates = ON
配置修改完成后,重启两台 MySQL 服务:
systemctl restart mysqld
2.2 创建复制账户和安全检查账户
在两台 MySQL 服务器上执行以下 SQL 命令,创建用于复制的账户:
-- 创建复制用户
CREATE USER IF NOT EXISTS 'myslave'@'%' IDENTIFIED BY '123456';-- 授权复制权限
GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'%';-- 创建检查用户
CREATE USER IF NOT EXISTS 'checker'@'localhost' IDENTIFIED BY 'CheckPass123';
-- USAGE权限表示"无权限",仅用于连接验证,是最安全的选项。
GRANT USAGE ON *.* TO 'checker'@'localhost'; -- 创建测试用户
CREATE USER IF NOT EXISTS 'test'@'%' IDENTIFIED BY '123456';
-- 授权
GRANT ALL ON *.* TO 'test'@'%';-- 刷新权限
FLUSH PRIVILEGES;
2.3 配置双向同步
2.3.1 在 Node1 上配置到 Node2 的复制
CHANGE MASTER TOMASTER_HOST = '192.168.10.15',MASTER_USER = 'myslave',MASTER_PASSWORD = '123456',MASTER_AUTO_POSITION = 1;START SLAVE;
2.3.2 在 Node2 上配置到 Node1 的复制
CHANGE MASTER TOMASTER_HOST = '192.168.10.14',MASTER_USER = 'myslave',MASTER_PASSWORD = '123456',MASTER_AUTO_POSITION = 1;START SLAVE;
2.4 验证复制状态
在两台服务器上执行以下命令,检查复制状态:
SHOW SLAVE STATUS\G;
确认以下关键指标:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0
(表示无延迟)
三、Keepalived 非抢占模式配置
3.1 安装 Keepalived
在两台服务器上安装 Keepalived:
yum install -y keepalived
3.2 配置 Keepalived
3.2.1 Node1 配置 (192.168.10.14)
创建或编辑 vim /etc/keepalived/keepalived.conf
:
! Configuration File for keepalivedglobal_defs {smtp_server 127.0.0.1# 路由器标识,每个节点唯一router_id MYSQL_HA_14#vrrp_strict
}# MySQL 健康检查脚本配置
vrrp_script chk_mysql {# 检查脚本路径script "/etc/keepalived/check_mysql.sh"# 每 2 秒检查一次interval 2# 连续 2 次失败视为故障fall 2# 1 次成功视为恢复rise 1
}# 虚拟路由配置
vrrp_instance VI_1 {# 两台均设为 BACKUP(非抢占关键)state BACKUP# 网卡名(根据实际系统情况修改)interface ens33# 虚拟路由 ID(两台必须相同)virtual_router_id 51# Node1 初始优先级 100(高于 Node2)priority 100# 非抢占模式(故障恢复不抢回 VIP)nopreempt# VRRP 通告间隔advert_int 1# 认证配置authentication {auth_type PASSauth_pass 1111 # 认证密码(两台相同)}# 虚拟 IP 配置virtual_ipaddress {192.168.10.180/24 dev ens33 # VIP}# 关联健康检查脚本track_script {chk_mysql}
}
3.2.2 Node2 配置 (192.168.10.15)
创建或编辑 vim /etc/keepalived/keepalived.conf
:
global_defs {smtp_server 127.0.0.1router_id MYSQL_HA_15#vrrp_strict
}vrrp_script chk_mysql {script "/etc/keepalived/check_mysql.sh"interval 2fall 2rise 1
}vrrp_instance VI_1 {state BACKUPinterface ens33virtual_router_id 51# Node2 初始优先级低于 Node1priority 90# 非抢占模式nopreemptadvert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.10.180/24 dev ens33}track_script {chk_mysql}
}
3.3 MySQL 健康检查脚本
在Node1和Node2上创建配置文件存储密码(避免明文)
# (权限设为 600,属主 root)
vim /etc/keepalived/.my.cnf
[client]
user=checker
password=CheckPass123
# 设置文件属主为 root(默认创建可能已是 root,但明确执行更稳妥)
chown root:root /etc/keepalived/.my.cnf# 设置权限为 600(仅 root 可读可写,其他用户无任何权限)
chmod 600 /etc/keepalived/.my.cnf
在Node1和Node2上创建健康检查脚本
vim /etc/keepalived/check_mysql.sh#!/bin/bash# 尝试连接 MySQL 并执行简单查询(如 SELECT 1)
if /usr/local/mysql/bin/mysql --defaults-extra-file=/etc/keepalived/.my.cnf -e "SELECT 1;" >/dev/null 2>&1; thenexit 0 # MySQL 可正常使用
elseexit 1 # MySQL 无法连接或查询失败
fi
给脚本添加执行权限:
chmod +x /etc/keepalived/check_mysql.sh
3.4 启动 Keepalived 服务
在两台服务器上启动 Keepalived 并设置开机自启:
systemctl start keepalived
systemctl enable keepalived
检查服务状态:
systemctl status keepalived
3.5 验证 VIP 绑定
在初始状态下,VIP 应该绑定在优先级较高的 Node1 上。可以使用以下命令验证:
ip addr show ens33
应该可以看到 VIP 192.168.10.180 绑定在 Node1 的网卡上。
3.6 测试使用VIP连接MySQL
# 在客户端使用vip连接mysql,测试能否正常使用
mysql -utest -p -h192.168.10.180 -P3306
show databases;
use test;
select * from test.info;
# 测试数据能否正常插入
insert into info values(3,'this is client');
# 在Node1和Node2上查看数据是否同步
select * from test.info;
四、故障转移与恢复流程
4.1 故障转移(Node1 节点故障)
当当前主节点(Node1)发生故障时,系统会自动进行故障转移:
# 关闭Node1节点mysql服务
systemctl stop mysqld
# 观察vip是否漂移到node2
ip addr show ens33
# 在客户端测试使用vip是否可以正常访问数据库
mysql -utest -p -h192.168.10.180 -P3306
show databases;
insert into info values(4,'this is client_2');
# 在node2(新主库)上查看数据是否正常插入
select * from test.info;
4.2 故障恢复(原主节点恢复)
当原主节点(Node1)故障修复后重新上线:
-
健康恢复:Node1 的 MySQL 服务恢复正常,健康检查脚本返回成功(exit 0)
-
非抢占行为:由于配置了
nopreempt
参数,Node1 不会主动抢回 VIP -
状态维持:VIP 仍然保留在 Node2,Node1 作为热备节点运行
-
数据同步:Node1 自动从 Node2 同步故障期间的数据更新,保持数据一致性
# node1上恢复mysql
systemctl start mysqld
# 查看Node1节点数据
select * from info;
# 在node1上手动开启slave
start slave;
# 观察Node1数据是否同步
select * from info;
4.3 强制切换回原主(可选操作)
如果需要在原主节点恢复后手动将 VIP 切换回 Node1,可以执行以下操作:
在 Node2 上执行(主动放弃 VIP):
systemctl restart keepalived
在非抢占模式下,通常需要重启 Keepalived 服务来触发切换。
五、方案优势与注意事项
5.1 方案优势
-
高可用性:自动故障检测和转移,确保数据库服务持续可用
-
无缝切换:VIP 机制使应用无需修改配置即可实现故障转移
-
数据一致性:基于 GTID 的主主复制保证数据双向同步
-
防止脑裂:VRRP 协议和优先级机制确保同一时间只有一台主节点
-
故障恢复安全:非抢占模式避免原主恢复后抢回 VIP 导致的服务波动
-
灵活可扩展:可轻松添加更多节点或扩展为多层级复制架构
5.2 注意事项
-
网络配置:确保防火墙允许 VRRP 协议(IP 协议号 112)和 MySQL 端口(3306)通信
-
复制监控:定期检查主主复制延迟和状态,确保数据同步正常
-
数据初始化:使用 mysqldump 或 XtraBackup 初始化数据时确保数据一致性
-
密码安全:脚本中的 MySQL 密码应妥善保管,建议使用权限受限的专用监控账户
-
脑裂预防:确保 Keepalived 配置中的
virtual_router_id
在同一网段内唯一 -
性能考虑:主主复制会增加服务器负载,需监控系统资源使用情况
总结
本文详细介绍了基于 MySQL 主主复制和 Keepalived 非抢占模式的高可用数据库集群方案。通过双向数据同步和虚拟 IP 漂移机制,实现了数据库服务的自动故障转移和恢复。非抢占模式的配置确保了故障恢复过程中的系统稳定性,避免了频繁的主备切换带来的风险。
此方案适用于对数据库可用性要求较高的生产环境,提供了无缝故障转移能力,同时保证了数据一致性。实际部署时,需要根据具体业务需求和系统环境进行适当调整和优化,并建立完善的监控告警机制,确保整个数据库集群的稳定运行。