MySQL 高可用实战(主主复制 + Keepalived+HAProxy)

一、MySQL 高可用基础认知

1. 核心定义

MySQL 高可用(HA)是通过节点冗余、数据同步、故障自动切换 ,让数据库在单节点宕机、网络中断时持续提供服务,实现业务零停机、数据不丢失

2. 经典架构组成

  • MySQL 主主复制:双节点互为主从,双向同步数据,双写提升性能
  • HAProxy:负载均衡 + 健康检查,自动剔除故障节点,分发流量
  • Keepalived:基于 VRRP 协议管理 VIP,故障时秒级漂移 VIP,保证访问地址不变

3. 架构优势

  • 秒级故障切换,无单点故障
  • 双节点并发写入,读请求负载分担
  • 开源无锁定,运维成本低
  • 横向扩展灵活,适配电商、金融等高并发场景

二、实验环境规划(测试机需要安装mysql

命令:dnf -y install mysqld(不需要启动,

表格

节点角色 系统版本 IP 地址 部署服务
MySQL 主 1 openEuler 24.03 192.168.10.101 MySQL 8.0.36
MySQL 主 2 openEuler 24.03 192.168.10.102 MySQL 8.0.36
代理节点 1 openEuler 24.03 192.168.10.103 HAProxy+Keepalived
代理节点 2 openEuler 24.03 192.168.10.104 HAProxy+Keepalived
虚拟 IP 192.168.10.100 业务统一访问入口(在代理)

三、分步部署(含完整代码)

(一)MySQL 双节点安装(主 1、主 2 均执行)

  1. 基础环境配置

bash

运行

复制代码
# 安装基础依赖
yum -y install gcc vim wget net-tools lrzsz
dnf install -y libaio numactl openssl ncurses-compat-libs

# 创建MySQL专用用户
useradd -M -s /sbin/nologin mysql

# 关闭SELinux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce 0

# 关闭防火墙
systemctl disable --now firewalld
  1. 二进制安装 MySQL 8.0.36

bash

运行

复制代码
# 解压并移动目录
tar xJf mysql-8.0.36-linux-glibc2.28-x86_64.tar.xz
mv mysql-8.0.36-linux-glibc2.28-x86_64 /usr/local/mysql

# 创建数据目录
mkdir -p /usr/local/mysql/data
chown -R mysql.mysql /usr/local/mysql/data

# 初始化MySQL(记录临时密码)
cd /usr/local/mysql/bin
./mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
  1. MySQL 配置文件(/etc/my.cnf)

ini

复制代码
[client]
socket=/usr/local/mysql/data/mysql.sock

[mysqld]
socket=/usr/local/mysql/data/mysql.sock
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port=3306
bind-address=0.0.0.0
skip-name-resolve
max_connections=2048
character-set-server=utf8
default-storage-engine=INNODB
max_allowed_packet=16M
  1. 配置环境变量与系统服务

bash

运行

复制代码
# 添加环境变量
echo "export PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
source /etc/profile

# 配置systemd服务
cp /usr/local/mysql/support-files/mysql.server /etc/rc.d/init.d/mysqld
chmod +x /etc/rc.d/init.d/mysqld

vim /lib/systemd/system/mysqld.service

ini

复制代码
[Unit]
Description=mysqld
After=network.target

[Service]
Type=forking
ExecStart=/etc/rc.d/init.d/mysqld start
ExecReload=/etc/rc.d/init.d/mysqld restart
ExecStop=/etc/rc.d/init.d/mysqld stop
PrivateTmp=true

[Install]
WantedBy=multi-user.target

bash

运行

复制代码
# 启动并设置开机自启
systemctl daemon-reload
systemctl enable --now mysqld

# 修改root密码(替换临时密码)
mysqladmin -u root -p 临时密码 password 'pwd123'
  1. 创建测试用户(主 1、主 2 均执行)

sql

复制代码
mysql -u root -ppwd123
CREATE USER 'test'@'192.168.10.%' IDENTIFIED BY '123456';
GRANT ALL ON *.* TO 'test'@'192.168.10.%';
ALTER USER 'test'@'192.168.10.%' IDENTIFIED WITH mysql_native_password BY '123456';
FLUSH PRIVILEGES;
exit

(二)配置 MySQL 主主复制

  1. 主 1 配置(/etc/my.cnf 新增)

ini

复制代码
log-bin=/usr/local/mysql/data/mysql-bin
binlog_format=MIXED
server-id=1
  1. 主 2 配置(/etc/my.cnf 新增)

ini

复制代码
log-bin=/usr/local/mysql/data/mysql-bin
binlog_format=MIXED
server-id=2
  1. 重启 MySQL 并授权同步用户

bash

运行

复制代码
systemctl restart mysqld

sql

复制代码
mysql -u root -ppwd123
CREATE USER 'myslave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'%';
ALTER USER 'myslave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
FLUSH PRIVILEGES;
show master status;  # 记录File和Position
exit
  1. 双向同步配置
  • 主 1 指向主 2

sql

复制代码
mysql -u root -ppwd123
change master to master_host='192.168.10.102',master_user='myslave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=157;
start slave;
show slave status\G  # 检查Slave_IO_Running、Slave_SQL_Running均为YES
exit
  • 主 2 指向主 1

sql

复制代码
mysql -u root -ppwd123
change master to master_host='192.168.10.101',master_user='myslave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=157;
start slave;
show slave status\G  # 检查双YES
exit

(三)HAProxy 安装配置(代理 1、代理 2 均执行)

bash

运行

复制代码
# 安装HAProxy
dnf install -y haproxy

# 备份并修改配置文件
cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
vim /etc/haproxy/haproxy.cfg

ini

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

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

listen mysql
    bind 0.0.0.0:3306
    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

bash

运行

复制代码
# 检查配置并启动
haproxy -c -f /etc/haproxy/haproxy.cfg
systemctl enable --now haproxy

然后在主上面授权给客户端用户登录(

测试机需要安装mysql

命令:dnf -y install mysqld(不需要启动,

复制代码
#创建用户
create user 'test'@'%' identified by '123456';

#授权
grant all on *.* to 'test'@'%';

#修改认证方式(兼容旧客户端)
alter user 'test'@'%' identified with mysql_native_password by '123456';

# 测试连接(在客户端
mysql -utest -p123456 -h192.168.10.103 -P3306 

(四)Keepalived 安装配置(代理 1、代理 2 均执行)

  1. 安装服务

bash

运行

复制代码
dnf install -y keepalived
  1. 代理 1 配置(/etc/keepalived/keepalived.conf)

ini

复制代码
global_defs {
    router_id r1
}

vrrp_script chk_haproxy {
    script "/etc/keepalived/chk.sh"
    interval 2
}

vrrp_instance VI_1 {
    state BACKUP
    nopreempt
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.10.100
    }
    track_script {
        chk_haproxy
    }
    notify_backup "/etc/init.d/haproxy restart"
    notify_fault "/etc/init.d/haproxy stop"
}
  1. 代理 2 配置(/etc/keepalived/keepalived.conf)

ini

复制代码
global_defs {
    router_id r2
}

vrrp_script chk_haproxy {
    script "/etc/keepalived/chk.sh"
    interval 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 99
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.10.100
    }
    track_script {
        chk_haproxy
    }
    notify_backup "/etc/init.d/haproxy restart"
    notify_fault "/etc/init.d/haproxy stop"
}
  1. 健康检查脚本(chk.sh

bash

运行

复制代码
vim /etc/keepalived/chk.sh
#!/bin/bash
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then
    systemctl stop keepalived
fi

bash

运行

复制代码
chmod +x /etc/keepalived/chk.sh
systemctl enable --now keepalived

# 查看VIP
ip a
  1. VIP 连接测试

bash

运行

复制代码
mysql -utest -p123456 -h192.168.10.100

(五)故障转移测试

  1. 关闭 MySQL 主 1,VIP 仍可正常连接数据库,HAProxy 自动剔除故障节点
  2. 关闭代理 1,VIP 秒级漂移至代理 2,业务无中断
  3. 恢复节点,非抢占模式下 VIP 不回切,避免流量抖动

四、补充核心知识点

1. 主主复制关键注意点

  • server-id 必须唯一,否则同步失败
  • 避免双节点同时写入同一条数据,引发主键冲突
  • MySQL 8.0 需切换认证插件为mysql_native_password,兼容同步

2. HAProxy 负载均衡算法

  • leastconn:最少连接数,适合长连接数据库场景
  • roundrobin:轮询,适合短连接均匀分发
  • source:源 IP 哈希,保证同一客户端访问同一节点

3. Keepalived 核心原理

  • 基于VRRP 协议,多节点组成虚拟路由
  • nopreempt:非抢占模式,避免节点恢复后 VIP 频繁切换
  • 健康检查脚本:关联 HAProxy 状态,代理失效则释放 VIP

4. 高可用核心指标

  • RTO:恢复时间目标,本架构秒级切换
  • RPO:恢复点目标,主主复制接近零数据丢失

五、架构总结

MySQL 主主复制保证数据双活冗余 ,HAProxy 实现流量负载均衡 ,Keepalived 提供VIP 故障漂移 ,三者协同打造高可用、高性能、易运维的数据库集群,完全满足生产环境业务连续性要求

相关推荐
大空大地20262 小时前
数据访问技术
数据库
天草二十六_简村人2 小时前
阿里云SLS采集jvm日志(上)
java·运维·数据库·后端·阿里云·容器·云计算
buhuimaren_3 小时前
mysql高可用
adb
Java面试题总结3 小时前
MongoDB(70)如何使用副本集进行备份?
数据库·mongodb
荒川之神3 小时前
Oracle LEVEL 函数练习(HR 模式 employees 表)
数据库·oracle
TDengine (老段)3 小时前
TDengine IDMP 工业数据建模 —— 元素与数据查询
大数据·数据库·人工智能·物联网·时序数据库·tdengine·涛思数据
蜡台3 小时前
Mysql 安装与配置
数据库·mysql
lajidecrd3 小时前
Ubuntu24安装PostgreSQL和PgVector
数据库·postgresql