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 故障漂移 ,三者协同打造高可用、高性能、易运维的数据库集群,完全满足生产环境业务连续性要求

相关推荐
2401_832365527 分钟前
SQL窗口函数与递归查询的区别_如何根据场景选择
jvm·数据库·python
u0109147607 分钟前
c++如何处理文件路径中由于不规范的连续斜杠导致的路径解析错误【避坑】
jvm·数据库·python
2301_796588509 分钟前
PHP源码开发用二手硬件划算吗_性价比与稳定性权衡【操作】
jvm·数据库·python
2301_7751481510 分钟前
如何通过C#读取Oracle数据库中的图片显示到WinForm_BLOB转Byte[]与流处理
jvm·数据库·python
ERBU DISH10 分钟前
修改表字段属性,SQL总结
java·数据库·sql
treesforest20 分钟前
IP 反欺诈查询怎么落地更稳?Ipdatacloud 适用场景与实战决策闭环
网络·数据库·网络协议·tcp/ip·网络安全
weixin_5689960630 分钟前
mysql如何配置大页内存_mysql large-pages开启方法
jvm·数据库·python
HHHHH1010HHHHH30 分钟前
HTML怎么创建评论区域_HTML嵌套评论语义结构【详解】
jvm·数据库·python
Absurd58731 分钟前
C#怎么模拟键盘按键输入_C#如何实现自动化脚本【教程】
jvm·数据库·python
Chasing__Dreams35 分钟前
Redis--基础知识点--29--Redis瓶颈
数据库·redis·php