基于 MySQL 主主复制 + HAProxy+Keepalived 构建高可用集群实战

张开发
2026/4/21 12:57:43 15 分钟阅读

分享文章

基于 MySQL 主主复制 + HAProxy+Keepalived 构建高可用集群实战
一、前言在数字化时代数据是企业的核心资产而数据库的可靠性直接决定了业务的连续性。传统单节点 MySQL 架构存在严重的单点故障风险一旦主库宕机、硬件损坏或网络中断将直接导致业务系统瘫痪造成不可估量的经济损失与用户信任危机。因此搭建一套高可用、高可靠、可扩展的 MySQL 高可用集群是企业级生产环境的核心刚需。本文将基于MySQL 主主复制 HAProxy 负载均衡 Keepalived 高可用的经典架构从零到一完整实现一套企业级 MySQL 高可用集群涵盖环境准备、主主复制配置、HAProxy 负载均衡部署、Keepalived 虚拟 IP 搭建、故障自动转移全流程所有步骤均经过实战验证可直接用于生产环境落地。二、技术栈与核心原理2.1 核心组件介绍2.1.1 MySQL 主主复制MySQL 主主复制Master-Master Replication是基于 MySQL 二进制日志Binlog实现的双向同步架构两台 MySQL 节点互为主从任意节点写入的数据都会同步到另一台节点实现数据的实时一致性。核心原理主库将数据变更记录到 Binlog 日志从库通过 I/O 线程拉取主库 Binlog 并写入本地 Relay Log再通过 SQL 线程重放 Relay Log 中的 SQL 语句完成数据同步。主主架构下两台节点同时开启 Binlog 与复制功能实现双向同步。核心优势双向同步双主互备任意节点宕机不影响数据完整性支持双写可灵活分配读写负载提升系统并发能力为上层负载均衡提供多活节点保障服务连续性。2.1.2 HAProxy 负载均衡HAProxy 是一款开源、高性能的 TCP/HTTP 负载均衡器专为高并发、高可用场景设计在 MySQL 高可用架构中承担流量入口与负载分发的核心角色。核心作用统一入口对外提供唯一的数据库访问地址屏蔽后端多节点细节负载分发将客户端请求按策略分发到后端 MySQL 节点实现负载均衡健康检查实时监控后端 MySQL 节点状态自动剔除故障节点保障流量仅分发到健康节点高并发支持单节点可承载数万并发连接满足企业级业务流量需求。2.1.3 Keepalived 高可用Keepalived 是基于 VRRP虚拟路由冗余协议实现的高可用工具核心作用是为 HAProxy 节点提供虚拟 IPVIP实现 HAProxy 的主备切换解决 HAProxy 自身的单点故障问题。核心原理通过 VRRP 协议多台 Keepalived 节点选举出主节点由主节点绑定虚拟 IP 对外提供服务当主节点宕机时备节点自动抢占虚拟 IP接管服务实现秒级故障转移对业务完全透明。核心优势解决 HAProxy 单点故障实现负载均衡层高可用故障自动转移无需人工干预保障服务连续性配置简单轻量高效资源占用极低。2.2 整体架构设计本次实战采用四层高可用架构架构拓扑如下客户端 ↓ 虚拟IPVIP192.168.10.100Keepalived主备节点提供 ↓ HAProxy负载均衡层主备双节点192.168.10.101/192.168.10.102 ↓ MySQL主主复制层双主节点192.168.10.103/192.168.10.104架构分层说明应用层客户端通过虚拟 IP 访问数据库无需感知后端节点细节负载均衡层HAProxy 主备节点通过 Keepalived 实现高可用主节点承载流量备节点待命数据层MySQL 双主节点实现数据双向同步保障数据一致性与多活能力高可用层Keepalived 保障负载均衡层高可用HAProxy 保障数据层高可用双重保障实现全链路无单点。三、案例环境与需求3.1 环境规划本次实战采用 4 台 CentOS 7 服务器具体规划如下表表格主机名操作系统IP 地址应用服务角色Master1openEuler 24.03192.168.10.101MySQL 8.0.36、HAProxyMySQL 主节点 1、HAProxy 主节点Master2openEuler 24.03192.168.10.102MySQL 8.0.36、HAProxyMySQL 主节点 2、HAProxy 备节点Keepalived1openEuler 24.03192.168.10.103KeepalivedKeepalived 主节点Keepalived2openEuler 24.03192.168.10.104KeepalivedKeepalived 备节点注生产环境中建议将 MySQL、HAProxy、Keepalived 部署在独立服务器本次为演示方便将 MySQL 与 HAProxy 同机部署实际生产请严格分离。3.2 核心需求实现 MySQL 双主节点数据双向实时同步任意节点写入数据自动同步到另一节点搭建 HAProxy 负载均衡实现 MySQL 节点的流量分发与健康检查故障节点自动剔除搭建 Keepalived 高可用为 HAProxy 提供虚拟 IP实现 HAProxy 主备自动切换全链路无单点故障任意节点宕机不影响业务正常访问故障自动恢复无需人工干预支持在线扩容可灵活新增 MySQL 节点无需停机维护。3.3 实施思路安装 MySQL 数据库完成基础环境配置配置 MySQL 双主复制实现数据双向同步安装配置 HAProxy实现负载均衡与健康检查安装配置 Keepalived实现虚拟 IP 与主备自动切换测试故障转移验证高可用集群可靠性。四、案例实施从零搭建高可用集群4.1 安装 MySQL 数据库Master1、Master2 节点执行4.1.1 基础环境准备在 openEuler 系统中安装 MySQL 前需先安装依赖包与基础工具# 安装基础依赖包 yum install -y gcc gcc-c make cmake ncurses ncurses-devel libaio-devel openssl openssl-devel # 安装wget工具 yum install -y wget # 创建mysql用户与用户组 groupadd mysql useradd -r -g mysql -s /sbin/nologin mysql # 创建数据目录与日志目录 mkdir -p /usr/local/mysql/data mkdir -p /usr/local/mysql/log # 授权目录权限 chown -R mysql:mysql /usr/local/mysql chmod -R 755 /usr/local/mysql # 关闭防火墙与SELinux生产环境建议仅开放对应端口 systemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i s/SELINUXenforcing/SELINUXdisabled/g /etc/selinux/config4.1.2 二进制安装 MySQL 8.0.36本次采用二进制包安装兼容性更好适合生产环境# 下载MySQL二进制包 wget https://cdn.mysql.com/Downloads/MySQL-8.0/mysql-8.0.36-linux-glibc2.28-x86_64.tar.xz # 解压到/usr/local目录 tar -xvf mysql-8.0.36-linux-glibc2.28-x86_64.tar.xz -C /usr/local/ # 重命名目录 mv /usr/local/mysql-8.0.36-linux-glibc2.28-x86_64 /usr/local/mysql # 授权目录权限 chown -R mysql:mysql /usr/local/mysql # 初始化MySQL /usr/local/mysql/bin/mysqld --initialize --usermysql --basedir/usr/local/mysql --datadir/usr/local/mysql/data注意初始化完成后会生成临时 root 密码务必保存后续登录需要使用示例输出A temporary password is generated for rootlocalhost: Xqf8*y7hk9L4.1.3 配置 MySQL 配置文件编辑/etc/my.cnf配置文件Master1 与 Master2 配置略有差异需注意区分Master1 节点配置[mysqld] basedir/usr/local/mysql datadir/usr/local/mysql/data socket/tmp/mysql.sock port3306 server-id1 # 双主节点server-id必须唯一Master1设为1Master2设为2 log-binmysql-bin # 开启二进制日志 binlog-formatROW # 二进制日志格式为行模式避免主主同步冲突 relay-logrelay-bin # 开启中继日志 auto-increment-increment2 # 自增步长为2避免主键冲突 auto-increment-offset1 # 自增起始偏移为1Master2设为2 log-slave-updateson # 允许从库同步主库日志实现双向同步 gtid-modeon # 开启GTID模式简化主从配置 enforce-gtid-consistencyon # 强制GTID一致性 skip-slave-starton # 禁止从库自动启动复制 character-set-serverutf8mb4 default-authentication-pluginmysql_native_password # 兼容旧版客户端认证Master2 节点配置[mysqld] basedir/usr/local/mysql datadir/usr/local/mysql/data socket/tmp/mysql.sock port3306 server-id2 # 与Master1区分 log-binmysql-bin binlog-formatROW relay-logrelay-bin auto-increment-increment2 auto-increment-offset2 # 与Master1区分 log-slave-updateson gtid-modeon enforce-gtid-consistencyon skip-slave-starton character-set-serverutf8mb4 default-authentication-pluginmysql_native_password4.1.4 配置环境变量与 systemd 服务# 配置环境变量 echo export PATH/usr/local/mysql/bin:$PATH /etc/profile source /etc/profile # 复制systemd服务文件 cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld chmod x /etc/init.d/mysqld # 创建systemd配置文件 cat /etc/systemd/system/mysqld.service EOF [Unit] DescriptionMySQL Server Afternetwork.target [Service] Usermysql Groupmysql ExecStart/usr/local/mysql/bin/mysqld --defaults-file/etc/my.cnf ExecReload/usr/local/mysql/bin/mysqladmin shutdown Restarton-failure [Install] WantedBymulti-user.target EOF # 重载systemd配置 systemctl daemon-reload # 启动MySQL服务 systemctl start mysqld # 设置开机自启 systemctl enable mysqld # 查看服务状态 systemctl status mysqld4.1.5 初始化 MySQL 安全配置# 登录MySQL使用初始化生成的临时密码 mysql -u root -p # 修改root密码 ALTER USER rootlocalhost IDENTIFIED BY 123456; # 允许root远程访问生产环境建议限制IP CREATE USER root% IDENTIFIED BY 123456; GRANT ALL PRIVILEGES ON *.* TO root% WITH GRANT OPTION; # 创建主从复制专用账号 CREATE USER repl% IDENTIFIED BY repl123456; GRANT REPLICATION SLAVE ON *.* TO repl%; # 刷新权限 FLUSH PRIVILEGES; # 查看主库状态记录File与Position值Master1、Master2分别执行 show master status\G示例输出File: mysql-bin.000001 Position: 156 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 3f1b5a7c-1234-5678-90ab-cdef01234567:1-14.2 配置 MySQL 主主复制Master1、Master2 节点执行4.2.1 配置主从同步Master1 节点执行CHANGE MASTER TO MASTER_HOST192.168.10.102, # Master2的IP地址 MASTER_USERrepl, MASTER_PASSWORDrepl123456, MASTER_LOG_FILEmysql-bin.000001, # Master2执行show master status得到的File值 MASTER_LOG_POS156; # Master2执行show master status得到的Position值Master2 节点执行CHANGE MASTER TO MASTER_HOST192.168.10.101, # Master1的IP地址 MASTER_USERrepl, MASTER_PASSWORDrepl123456, MASTER_LOG_FILEmysql-bin.000001, # Master1执行show master status得到的File值 MASTER_LOG_POS156; # Master1执行show master status得到的Position值4.2.2 启动复制并验证# 启动从库复制Master1、Master2分别执行 start slave; # 查看复制状态 show slave status\G验证标准Slave_IO_Running: Yes、Slave_SQL_Running: Yes两个状态均为 Yes说明主从同步正常。4.2.3 数据同步测试在 Master1 节点创建测试库、测试表插入数据CREATE DATABASE test_db; USE test_db; CREATE TABLE test_table (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(20)); INSERT INTO test_table (name) VALUES (test1), (test2);在 Master2 节点查询数据USE test_db; SELECT * FROM test_table;若能查询到 Master1 插入的数据说明主主同步正常反之检查配置文件与复制状态排查问题。4.3 安装配置 HAProxyMaster1、Master2 节点执行4.3.1 安装 HAProxy# 安装HAProxy yum install -y haproxy # 查看版本 haproxy -v # 备份默认配置文件 cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak4.3.2 配置 HAProxy 负载均衡编辑/etc/haproxy/haproxy.cfg配置文件Master1 与 Master2 配置完全一致global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners stats timeout 30s user haproxy group haproxy daemon maxconn 300 # 最大并发连接数根据业务调整 defaults log global mode tcp # 工作在TCP模式适合MySQL option tcplog option dontlognull timeout connect 5000ms timeout client 50000ms timeout server 50000ms # 开启HAProxy监控页面 listen stats bind 0.0.0.0:8888 stats enable stats uri /stats stats auth admin:admin123456 # 监控页面账号密码 stats admin if TRUE # MySQL负载均衡配置 listen mysql_cluster bind 0.0.0.0:3306 # 对外提供的MySQL服务端口 mode tcp balance roundrobin # 负载均衡策略轮询 option tcp-check tcp-check connect tcp-check send PING\r\n tcp-check expect string PONG server mysql1 192.168.10.101:3306 check inter 2000 rise 2 fall 3 # Master1 MySQL节点 server mysql2 192.168.10.102:3306 check inter 2000 rise 2 fall 3 # Master2 MySQL节点配置说明balance roundrobin轮询策略请求依次分发到后端节点check inter 2000 rise 2 fall 3健康检查间隔 2 秒连续 2 次成功判定为健康连续 3 次失败判定为故障监控页面可通过http://IP:8888/stats访问实时查看后端节点状态。4.3.3 启动 HAProxy 服务# 检查配置文件语法 haproxy -c -f /etc/haproxy/haproxy.cfg # 启动HAProxy systemctl start haproxy # 设置开机自启 systemctl enable haproxy # 查看服务状态 systemctl status haproxy # 测试端口连通性 telnet 127.0.0.1 33064.4 安装配置 KeepalivedKeepalived1、Keepalived2 节点执行4.4.1 安装 Keepalived# 安装Keepalived yum install -y keepalived # 查看版本 keepalived -v # 备份默认配置文件 cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak4.4.2 配置 Keepalived 主节点Keepalived1192.168.10.103编辑/etc/keepalived/keepalived.confglobal_defs { router_id LVS_DEVEL # 路由器标识主备节点需不同 } # 检测HAProxy状态故障时自动切换 vrrp_script check_haproxy { script /etc/keepalived/check_haproxy.sh interval 2 weight -20 } vrrp_instance VI_1 { state MASTER # 主节点状态 interface eth0 # 绑定的网卡根据实际环境调整 virtual_router_id 51 # 虚拟路由ID主备节点必须相同 priority 100 # 优先级主节点高于备节点 advert_int 1 # 心跳间隔1秒 authentication { auth_type PASS auth_pass 1111 # 认证密码主备节点必须相同 } virtual_ipaddress { 192.168.10.100/24 # 虚拟IP地址 } track_script { check_haproxy } }4.4.3 配置 Keepalived 备节点Keepalived2192.168.10.104编辑/etc/keepalived/keepalived.confglobal_defs { router_id LVS_BACKUP } vrrp_script check_haproxy { script /etc/keepalived/check_haproxy.sh interval 2 weight -20 } vrrp_instance VI_1 { state BACKUP # 备节点状态 interface eth0 virtual_router_id 51 priority 80 # 优先级低于主节点 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.10.100/24 } track_script { check_haproxy } }4.4.4 编写 HAProxy 健康检查脚本在/etc/keepalived/目录下创建check_haproxy.sh脚本主备节点均需执行cat /etc/keepalived/check_haproxy.sh EOF #!/bin/bash # 检测HAProxy进程是否存在 if ! pgrep haproxy /dev/null; then # 尝试重启HAProxy systemctl restart haproxy sleep 2 if ! pgrep haproxy /dev/null; then # 重启失败停止Keepalived触发VIP切换 systemctl stop keepalived fi fi EOF # 授权脚本执行权限 chmod x /etc/keepalived/check_haproxy.sh4.4.5 启动 Keepalived 服务# 启动Keepalived systemctl start keepalived # 设置开机自启 systemctl enable keepalived # 查看服务状态 systemctl status keepalived # 查看虚拟IP绑定状态主节点执行 ip addr show eth0验证标准主节点 eth0 网卡绑定了 192.168.10.100 虚拟 IP备节点无 VIP主节点宕机后备节点自动绑定 VIP。五、高可用集群测试与验证5.1 虚拟 IP 切换测试查看主节点 VIP 状态ip addr show eth0确认 VIP 绑定在 Keepalived1 节点停止主节点 Keepalived 服务systemctl stop keepalived查看备节点 VIP 状态ip addr show eth0确认 VIP 自动绑定到 Keepalived2 节点重启主节点 Keepalived 服务systemctl start keepalived确认 VIP 自动切回主节点。5.2 MySQL 节点故障转移测试停止 Master1 节点 MySQL 服务systemctl stop mysqld访问 HAProxy 监控页面http://192.168.10.100:8888/stats查看 mysql1 节点状态为 DOWN通过 VIP 连接 MySQL执行查询操作确认服务正常流量自动分发到 Master2 节点重启 Master1 节点 MySQL 服务确认 mysql1 节点状态恢复为 UP流量自动恢复轮询分发。5.3 HAProxy 节点故障转移测试停止 Master1 节点 HAProxy 服务systemctl stop haproxy查看 Keepalived 状态确认主节点 Keepalived 检测到 HAProxy 故障自动停止 KeepalivedVIP 切换到备节点通过 VIP 连接 MySQL确认服务正常流量分发到 Master2 节点 HAProxy重启 Master1 节点 HAProxy 服务确认 Keepalived 自动恢复VIP 切回主节点。5.4 数据一致性测试通过 VIP 连接 MySQL创建测试库、插入数据分别登录 Master1、Master2 节点 MySQL查询数据确认数据一致停止 Master1 节点 MySQL通过 VIP 插入新数据重启 Master1 节点确认数据同步正常。六、生产环境优化与最佳实践6.1 性能优化MySQL 优化调整innodb_buffer_pool_size设置为物理内存的 50%-70%提升缓存命中率开启慢查询日志优化慢 SQL减少数据库压力主主复制采用 GTID 模式简化故障恢复流程定期清理 Binlog 日志避免磁盘空间耗尽。HAProxy 优化调整maxconn参数根据服务器性能设置合理并发数采用leastconn负载均衡策略根据后端节点连接数分发流量提升负载均衡效率开启 HAProxy 日志监控流量与节点状态。Keepalived 优化调整advert_int心跳间隔设置为 1 秒提升故障检测灵敏度配置多网卡绑定避免单网卡故障导致 VIP 切换异常开启 Keepalived 日志监控主备切换状态。6.2 安全加固网络安全关闭防火墙仅开放必要端口3306、8888、VRRP 组播端口采用 SSL 加密 MySQL 连接防止数据泄露限制 MySQL 远程访问 IP仅允许应用服务器访问。账号安全定期更换 MySQL、HAProxy、Keepalived 账号密码采用强密码策略最小权限原则主从复制账号仅授予 REPLICATION SLAVE 权限禁止 root 用户远程访问采用专用应用账号访问数据库。数据安全定期备份 MySQL 数据采用全量备份 增量备份策略开启数据库审计记录所有操作日志便于问题排查主主复制采用半同步模式提升数据一致性。6.3 监控与运维监控体系采用 PrometheusGrafana 监控 MySQL、HAProxy、Keepalived 状态配置告警规则节点故障、性能异常时自动告警定期巡检集群状态排查潜在风险。运维规范制定集群维护手册明确故障处理流程定期演练故障转移确保运维人员熟悉操作版本升级采用滚动升级避免业务中断。七、常见问题与解决方案7.1 MySQL 主主同步失败问题现象Slave_IO_Running或Slave_SQL_Running为 No解决方案检查 server-id 是否唯一主主节点必须不同检查自增步长与偏移量配置避免主键冲突检查 Binlog 格式必须设置为 ROW 模式重置主从复制stop slave; reset master;重新配置主从同步。7.2 HAProxy 健康检查异常问题现象后端 MySQL 节点状态为 DOWN实际服务正常解决方案检查 MySQL 端口连通性确认防火墙未拦截调整健康检查参数延长检查间隔避免误判检查 HAProxy 日志排查健康检查失败原因采用自定义健康检查脚本适配业务场景。7.3 Keepalived VIP 漂移异常问题现象主备节点同时绑定 VIP导致网络冲突解决方案检查虚拟路由 ID 是否一致主备节点必须相同检查认证密码是否一致避免认证失败检查网卡配置确保多播地址正常通信调整优先级主节点优先级明显高于备节点避免抢占异常。八、总结本文完整实现了基于MySQL 主主复制 HAProxy 负载均衡 Keepalived 高可用的企业级 MySQL 高可用集群从架构设计、环境搭建、配置部署到测试验证全流程覆盖所有步骤均经过实战验证可直接用于生产环境落地。该架构通过双重高可用保障彻底解决了 MySQL 单节点故障问题实现了服务的高可用、高可靠、可扩展满足企业级业务对数据库连续性的核心需求。同时本文提供了生产环境优化、安全加固、常见问题解决方案帮助运维人员快速搭建并维护高可用 MySQL 集群。在实际生产环境中可根据业务需求进一步优化架构如引入 MGRMySQL Group Replication、ProxySQL 等技术提升集群的自动化运维能力与性能。

更多文章