Mysql高可用群集

摘要

在企业级生产环境中,MySQL 作为核心关系型数据库,单点故障会直接导致业务中断、数据丢失等严重后果。本文基于 CentOS 系统,从零搭建一套MySQL 主从复制 + HAProxy 负载均衡 + Keepalived 双机热备的高可用架构,实现数据实时同步、读写请求负载分发、故障自动切换三大核心能力。文章包含完整部署步骤、关键配置解析、故障模拟测试与排坑指南,同时补充了架构原理、性能优化与生产环境最佳实践,帮助运维人员快速掌握企业级数据库高可用方案的落地方法。


一、架构总览与原理剖析

1.1 架构设计图

本次搭建的架构包含 3 个核心组件,各司其职又协同工作:

  • MySQL 主从复制:2 台 MySQL 节点互为主从,实现数据双向同步,解决单点数据故障问题。
  • HAProxy:作为 TCP 代理,将客户端请求分发到健康的 MySQL 节点,实现负载均衡与故障节点剔除。
  • Keepalived:通过 VRRP 协议实现双机热备,提供虚拟 IP(VIP),客户端只需连接 VIP 即可访问数据库,后端故障对业务透明。

1.2 各组件核心原理

1.2.1 MySQL 主从复制原理

MySQL 主从复制基于 ** 二进制日志(Binlog)** 实现,核心流程如下:

  1. 主节点(Master)将所有数据变更记录到 Binlog 文件中。
  2. 从节点(Slave)的 IO 线程连接主节点,拉取 Binlog 并写入本地 Relay Log 文件。
  3. 从节点的 SQL 线程读取 Relay Log,回放其中的 SQL 语句,实现数据与主节点同步。本次采用双向主从复制,两台节点互为主备,可同时处理读写请求,避免传统主从架构中从节点只读的性能瓶颈。
1.2.2 HAProxy 负载均衡原理

HAProxy 作为四层 TCP 代理,监听 3306 端口,接收客户端的 MySQL 请求,通过配置的负载均衡算法(本次采用最少连接算法leastconn),将请求分发到后端健康的 MySQL 节点。同时通过健康检查,自动剔除故障节点,避免请求转发到不可用的实例上。

1.2.3 Keepalived 双机热备原理

Keepalived 基于 VRRP(虚拟路由冗余协议),在两台服务器之间选举出一台主节点,将虚拟 IP(VIP)绑定到主节点的网卡上。主节点定期发送心跳报文给备节点,若备节点在指定时间内未收到心跳,会自动接管 VIP,实现故障自动切换,整个过程业务侧无感知。


二、环境准备与前置配置

2.1 服务器规划

节点角色IP 地址系统版本部署服务
MySQL Master1192.168.10.101CentOS 7/8MySQL 8.0
MySQL Master2192.168.10.102CentOS 7/8MySQL 8.0
HAProxy1+Keepalived1192.168.10.103CentOS 7/8HAProxy 2.4、Keepalived 2.0
HAProxy2+Keepalived2192.168.10.104CentOS 7/8HAProxy 2.4、Keepalived 2.0
虚拟 IP(VIP)192.168.10.100-Keepalived 提供,对外访问入口

2.2 基础环境配置(所有节点执行)

2.2.1 关闭 SELinux 与防火墙

生产环境建议配置防火墙规则,测试环境可直接关闭:

bash

# 临时关闭SELinux
setenforce 0
# 永久关闭SELinux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
2.2.2 安装依赖包与时间同步

bash

yum install -y wget vim net-tools ntpdate
# 同步系统时间
ntpdate time.aliyun.com
echo "*/5 * * * * /usr/sbin/ntpdate time.aliyun.com" >> /var/spool/cron/root

三、MySQL 双向主从复制部署

3.1 MySQL 安装与基础配置

3.1.1 安装 MySQL(以 8.0 为例)

bash

# 下载MySQL YUM源
wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
yum localinstall -y mysql80-community-release-el7-3.noarch.rpm
yum install -y mysql-community-server
# 启动MySQL并设置开机自启
systemctl start mysqld
systemctl enable mysqld
3.1.2 初始化 MySQL 并修改 root 密码

bash

# 获取初始密码
grep "temporary password" /var/log/mysqld.log
# 登录MySQL修改密码
mysql -uroot -p
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Pwd@123456';
FLUSH PRIVILEGES;
3.1.3 配置/etc/my.cnf主从参数

Master1 节点配置:

ini

[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/data/mysql.sock
port=3306
bind-address=0.0.0.0
skip-name-resolve
# 主从复制核心配置
log-bin=/usr/local/mysql/data/mysql-bin
binlog_format=MIXED
server-id=1  # 两台节点ID必须不同,Master2设置为2
auto-increment-increment=2
auto-increment-offset=1
# 性能优化(适配2G内存)
innodb_buffer_pool_size=512M
max_connections=100
character-set-server=utf8
default-storage-engine=INNODB

Master2 节点只需修改server-id=2auto-increment-offset=2,其余配置与 Master1 保持一致。修改完成后重启 MySQL:

bash

systemctl restart mysqld

3.2 创建主从复制账号(两台节点都执行)

sql

-- 创建复制用户,允许指定IP连接
CREATE USER 'repl'@'192.168.10.%' IDENTIFIED BY '123456';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.10.%';
-- 刷新权限
FLUSH PRIVILEGES;

3.3 配置双向主从同步

3.3.1 查看主节点 Binlog 信息

在 Master1 上执行,获取当前 Binlog 文件名和位置:

sql

SHOW MASTER STATUS;

记录FilePosition字段的值,后续配置从节点时使用。

3.3.2 配置 Master2 作为 Master1 的从节点

sql

CHANGE MASTER TO
MASTER_HOST='192.168.10.101',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000001',  -- 替换为Master1的Binlog文件名
MASTER_LOG_POS=156;  -- 替换为Master1的Binlog位置
-- 启动从节点复制
START SLAVE;
-- 查看复制状态,确保Slave_IO_Running和Slave_SQL_Running都为Yes
SHOW SLAVE STATUS\G
3.3.3 配置 Master1 作为 Master2 的从节点

重复上述步骤,在 Master2 上执行SHOW MASTER STATUS获取 Binlog 信息,然后在 Master1 上配置:

sql

CHANGE MASTER TO
MASTER_HOST='192.168.10.102',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000001',  -- 替换为Master2的Binlog文件名
MASTER_LOG_POS=156;  -- 替换为Master2的Binlog位置
START SLAVE;
SHOW SLAVE STATUS\G

3.4 主从复制验证

在 Master1 上创建测试库和表,插入数据:

sql

CREATE DATABASE testdb;
USE testdb;
CREATE TABLE t1(id INT,name VARCHAR(20));
INSERT INTO t1 VALUES(1,'master1');

在 Master2 上查询数据,验证是否同步成功:

sql

SELECT * FROM testdb.t1;

反之在 Master2 插入数据,Master1 也能查询到,说明双向主从配置成功。


四、HAProxy 负载均衡部署

4.1 HAProxy 安装

在 103 和 104 两台节点上安装 HAProxy:

bash

yum install -y haproxy
systemctl enable haproxy

4.2 配置/etc/haproxy/haproxy.cfg

核心配置如下,两台节点配置完全一致:

ini

global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

defaults
    mode        tcp
    log         global
    option      tcplog
    option      dontlognull
    retries     3
    timeout     connect 5s
    timeout     client 1m
    timeout     server 1m
    timeout     check 5s
    maxconn     3000

# MySQL负载均衡配置
listen mysql
    bind 0.0.0.0:3306  # 监听所有IP的3306端口
    mode tcp
    balance leastconn  # 最少连接算法,分发请求到负载最低的节点
    server mysql1 192.168.10.101:3306 check port 3306 maxconn 300
    server mysql2 192.168.10.102:3306 check port 3306 maxconn 300

配置说明:

  • balance leastconn:优先将请求转发给当前连接数最少的 MySQL 节点,避免单节点压力过大。
  • check port 3306:HAProxy 会定期检测后端节点的 3306 端口,若端口不通则标记节点为故障,停止转发请求。

4.3 启动 HAProxy 并验证

bash

# 检查配置文件语法
haproxy -c -f /etc/haproxy/haproxy.cfg
# 启动服务
systemctl start haproxy
# 查看3306端口是否监听
netstat -tulnp | grep 3306

客户端测试连接,使用测试用户连接 HAProxy 的 IP:

bash

mysql -utest -p123456 -h192.168.10.103 -P3306

能成功登录 MySQL,说明 HAProxy 负载均衡配置成功。


五、Keepalived 双机热备部署

5.1 Keepalived 安装

在 103 和 104 两台节点上安装:

bash

yum install -y keepalived
systemctl enable keepalived

5.2 配置/etc/keepalived/keepalived.conf

5.2.1 Keepalived1(103 节点)配置

ini

global_defs {
    router_id r1  # 节点标识,两台节点不同
}

# 检测HAProxy状态的脚本
vrrp_script chk_haproxy {
    script "/etc/keepalived/chk.sh"
    interval 2  # 每2秒检测一次
}

vrrp_instance VI_1 {
    state BACKUP  # 两台节点都配置为BACKUP,避免抢占
    nopreempt     # 关闭抢占模式,故障恢复后不抢回VIP
    interface ens33  # 绑定的网卡,根据实际修改
    virtual_router_id 51  # 虚拟路由ID,两台节点必须相同
    priority 100  # 优先级,103节点优先级设为100,104设为99
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111  # 认证密码,两台节点必须相同
    }
    virtual_ipaddress {
        192.168.10.100/24  # 虚拟IP
    }
    track_script {
        chk_haproxy  # 关联HAProxy检测脚本
    }
    notify_backup "/etc/init.d/haproxy restart"
    notify_fault "/etc/init.d/haproxy stop"
}
5.2.2 Keepalived2(104 节点)配置

只需修改以下参数:

ini

router_id r2
priority 99
其余配置与103节点保持一致

5.3 编写 HAProxy 状态检测脚本/etc/keepalived/chk.sh

bash

#!/bin/bash
# 检测HAProxy进程是否存在
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then
    # 若进程不存在,停止Keepalived,触发VIP切换
    systemctl stop keepalived
fi

赋予脚本执行权限:

bash

chmod +x /etc/keepalived/chk.sh

5.4 启动 Keepalived 并验证 VIP

bash

# 启动服务
systemctl start keepalived
# 查看虚拟IP是否绑定成功(103节点)
ip a

输出中能看到192.168.10.100/24绑定在ens33网卡上,说明 Keepalived 配置成功。


六、高可用架构故障模拟与测试

6.1 测试场景 1:MySQL 主节点故障

  1. 手动停止 Master1 的 MySQL 服务:systemctl stop mysqld
  2. 查看 HAProxy 状态,发现mysql1节点被标记为故障,请求自动转发到 Master2。
  3. 客户端使用 VIP 连接 MySQL,依然能正常读写数据,业务无中断。

6.2 测试场景 2:HAProxy 主节点故障

  1. 手动停止 103 节点的 HAProxy 服务:systemctl stop haproxy
  2. Keepalived 检测脚本触发,103 节点的 Keepalived 自动停止,VIP 自动漂移到 104 节点。
  3. 客户端连接 VIP192.168.10.100,依然能正常访问 MySQL,业务侧无感知。

6.3 测试场景 3:Keepalived 主节点故障

  1. 手动停止 103 节点的 Keepalived 服务:systemctl stop keepalived
  2. 备节点 104 的 Keepalived 未收到心跳,自动接管 VIP。
  3. 客户端连接 VIP,访问正常,故障切换时间约 1-3 秒。

七、架构优化与生产环境最佳实践

7.1 MySQL 主从复制优化

  1. 半同步复制:在 MySQL 5.7 + 中开启半同步复制,确保主节点数据写入后,至少有一个从节点同步成功,避免数据丢失。
  2. Binlog 日志清理:配置expire_logs_days=7,自动清理 7 天前的 Binlog 文件,避免磁盘占满。
  3. 读写分离:结合中间件(如 MyCat、ShardingSphere)实现读写分离,读请求分发到从节点,减轻主节点压力。

7.2 HAProxy 优化

  1. 配置监控页面:开启 HAProxy 的统计页面,方便实时查看后端节点状态:

    ini

    listen stats
        bind :8080
        mode http
        stats enable
        stats uri /stats
        stats auth admin:admin@123
    
    浏览器访问http://192.168.10.103:8080/stats即可查看负载均衡状态。
  2. 调整最大连接数:根据业务并发量调整maxconn参数,避免连接数过多导致性能下降。

7.3 Keepalived 优化

  1. 故障切换告警:在notify_fault脚本中添加邮件或短信告警,及时通知运维人员故障发生。
  2. 日志配置:将 Keepalived 日志写入独立文件,方便故障排查:

    bash

    echo "local0.* /var/log/keepalived.log" >> /etc/rsyslog.conf
    systemctl restart rsyslog
    

7.4 安全加固

  1. MySQL 用户权限最小化:仅授予业务用户必要的权限,禁止使用 root 用户连接数据库。
  2. 防火墙规则配置:仅允许业务服务器 IP 访问 MySQL 的 3306 端口,禁止公网直接访问。
  3. 定期备份:使用mysqldump或 xtrabackup 定期备份数据,备份文件异地存储。

八、常见问题与排坑指南

8.1 MySQL 主从复制故障

  • 故障现象SHOW SLAVE STATUS\GSlave_IO_Running为 No。
  • 排查思路:检查主从节点网络连通性、复制用户权限、Binlog 文件和位置是否正确、防火墙是否放行 3306 端口。

8.2 HAProxy 无法转发请求

  • 故障现象:客户端连接 HAProxy 的 3306 端口超时。
  • 排查思路:检查 HAProxy 配置文件语法、后端 MySQL 节点状态、3306 端口是否被防火墙拦截、/var/log/haproxy.log日志报错信息。

8.3 Keepalived VIP 无法漂移

  • 故障现象:主节点故障后,VIP 未切换到备节点。
  • 排查思路:检查两台节点的virtual_router_id是否一致、认证密码是否相同、网卡配置是否正确、chk.sh脚本是否有执行权限。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kiku1818

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值