MySQL高可用集群

一、什么是MySQL高可用

1.1 核心定义

MySQL高可用,本质是通过架构设计和技术手段,最大限度减少数据库服务不可用时间,保障业务连续性和数据可靠性,核心目标是解决"单点故障"问题------即单个MySQL节点宕机、故障时,能快速切换到备用节点,避免业务中断、数据丢失,同时支撑业务高并发访问需求。

简单来说,高可用的核心是"不中断、不丢数",让数据库服务在故障场景下仍能正常对外提供服务,是生产环境中数据库部署的核心要求。

1.2 核心衡量指标

  • RTO(恢复时间目标):故障发生后,数据库服务恢复正常的最长可接受时间,生产核心场景要求RTO<30s,非核心场景RTO<5min。

  • RPO(恢复点目标):故障发生后,可接受的最大数据丢失量,核心交易场景要求RPO=0(无数据丢失),非核心场景RPO<30s。

1.3 高可用与普通部署的区别

普通单节点部署:结构简单,但存在单点故障,一旦节点宕机,整个数据库服务完全不可用,数据易丢失,仅适用于测试、开发等非生产场景。

高可用集群部署:多节点协同工作,存在主备/主主节点,故障时自动/手动切换,保障服务连续性,数据同步可靠,适用于生产、线上等高并发、高可靠需求场景。

二、MySQL高可用集群搭建

本次搭建以"主主复制 + Keepalived(虚拟IP漂移) + HAProxy(负载均衡)"为核心架构,适配生产级中小规模业务,兼顾高可用和高并发,步骤清晰、可直接落地,环境基于CentOS 7 + MySQL 8.0。

2.1 搭建前准备

2.1.1 服务器环境(4台服务器,最小配置)

  • MySQL主节点1(Master1):IP 192.168.1.10,CPU≥2核,内存≥4G,硬盘≥50G

  • MySQL主节点2(Master2):IP 192.168.1.11,配置与Master1一致(主主复制要求节点配置对等)

  • HAProxy节点1:IP 192.168.1.12,CPU≥2核,内存≥2G(负载均衡节点,可部署2台实现HA)

  • HAProxy节点2(可选,高可用负载):IP 192.168.1.13,配置与HAProxy节点1一致

2.1.2 环境初始化(所有节点执行)

1. 关闭防火墙和SELinux(生产可按需开放端口,临时关闭便于搭建)

systemctl stop firewalld

systemctl disable firewalld

setenforce 0

sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

2. 时间同步(避免数据同步因时间差异常)

yum install ntpdate -y

ntpdate ntp.aliyun.com

3. 安装依赖包

yum install -y wget gcc gcc-c++ make openssl-devel pcre-devel

2.1.3 安装MySQL 8.0(Master1、Master2节点)

1. 下载MySQL repo源(注:原下载链接可能存在不支持该文件类型的报错,可更换为国内镜像源或直接通过yum仓库安装)

wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm

rpm -ivh mysql80-community-release-el7-3.noarch.rpm

2. 安装MySQL

yum install -y mysql-community-server

3. 启动MySQL并设置开机自启

systemctl start mysqld

systemctl enable mysqld

4. 查看初始密码(用于首次登录)

grep 'temporary password' /var/log/mysqld.log

5. 登录MySQL并修改密码(密码需符合复杂度:字母+数字+特殊符号)

mysql -u root -p

ALTER USER 'root'@'localhost' IDENTIFIED BY 'MySQL@123456';

grant all privileges on *.* to 'root'@'%' identified by 'MySQL@123456';

flush privileges;

exit;

2.2 搭建主主复制

主主复制是指两个MySQL节点互为主从,彼此同步数据,即Master1的修改同步到Master2,Master2的修改同步到Master1,解决单主复制中主节点故障后需手动切换的痛点,为后续高可用切换奠定基础。

2.2.1 配置Master1(192.168.1.10)

1. 编辑MySQL配置文件

vim /etc/my.cnf

2. 添加以下配置(核心参数,其余保持默认)

mysqld

server-id = 10 # 唯一标识,每个节点必须不同,建议用IP最后一段

log_bin = mysql-bin # 开启binlog日志(数据同步的核心)

binlog_format = ROW # 行级格式,避免主从不一致,生产必用

gtid_mode = ON # 开启GTID,自动定位同步位点,无需手动配置

enforce_gtid_consistency = ON # 强制GTID一致性

log_slave_updates = ON # 允许从库将同步的事务写入自身binlog(主主复制核心)

sync_binlog = 1 # 每提交1个事务,就将binlog刷到磁盘,保障数据不丢失

innodb_flush_log_at_trx_commit = 1 # 事务提交时,将redo log刷到磁盘

3. 重启MySQL生效

systemctl restart mysqld

2.2.2 配置Master2(192.168.1.11)

1. 编辑MySQL配置文件

vim /etc/my.cnf

2. 添加以下配置(server-id与Master1不同,其余参数一致)

mysqld

server-id = 11

log_bin = mysql-bin

binlog_format = ROW

gtid_mode = ON

enforce_gtid_consistency = ON

log_slave_updates = ON

sync_binlog = 1

innodb_flush_log_at_trx_commit = 1

3. 重启MySQL生效

systemctl restart mysqld

2.2.3 建立主主同步关系

步骤1:在Master1上授权Master2同步

mysql -u root -pMySQL@123456

授权同步用户(repl为同步用户名,123456为密码,%表示允许所有IP连接)

grant replication slave on *.* to 'repl'@'%' identified by 'Repl@123456';

flush privileges;

查看Master1状态(记录binlog文件和位置,后续配置Master2用)

show master status;

输出示例(无需复制,实际以自己的为准):

+------------------+----------+--------------+------------------+-------------------+

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+-------------------+

| mysql-bin.000001 | 156 | | | |

+------------------+----------+--------------+------------------+-------------------+

步骤2:在Master2上配置同步Master1

mysql -u root -pMySQL@123456

停止从库同步(首次配置可忽略)

stop slave;

配置同步Master1(替换Master1的IP、同步用户和密码,无需手动填binlog位置,GTID自动同步)

change master to

master_host='192.168.1.10',

master_user='repl',

master_password='Repl@123456',

master_auto_position=1; # 开启GTID自动定位

启动从库同步

start slave;

查看同步状态(确保Slave_IO_Running和Slave_SQL_Running均为Yes)

show slave status\G;

步骤3:在Master2上授权Master1同步(反向同步)

继续在Master2的MySQL终端执行

grant replication slave on *.* to 'repl'@'%' identified by 'Repl@123456';

flush privileges;

查看Master2状态(记录binlog信息,用于配置Master1同步)

show master status;

步骤4:在Master1上配置同步Master2(反向同步)

mysql -u root -pMySQL@123456

stop slave;

change master to

master_host='192.168.1.11',

master_user='repl',

master_password='Repl@123456',

master_auto_position=1;

start slave;

查看同步状态,确保Slave_IO_Running和Slave_SQL_Running均为Yes

show slave status\G;

验证主主复制
  1. 在Master1上创建数据库和表,插入数据:

create database test_ha;

use test_ha;

create table user(id int primary key auto_increment, name varchar(50));

insert into user(name) values('test1');

commit;

  1. 在Master2上查询,确认数据同步成功:

use test_ha;

select * from user; # 能查询到Master1插入的数据,说明同步正常

  1. 同理,在Master2上插入数据,在Master1上查询,验证反向同步正常,主主复制搭建完成。

2.3 安装配置HAProxy(负载均衡)

HAProxy是一款高性能的TCP/HTTP负载均衡工具,用于将客户端的数据库请求分发到两个MySQL主节点,实现负载分担,同时检测节点状态,故障节点自动剔除,保障请求正常转发。

2.3.1 安装HAProxy(192.168.1.12、192.168.1.13节点)

1. 下载HAProxy(以2.4.24版本为例,注:原下载链接可能存在网页解析失败报错,可更换版本或国内镜像源)

wget https://www.haproxy.org/download/2.4/src/haproxy-2.4.24.tar.gz

2. 解压并编译安装

tar -zxvf haproxy-2.4.24.tar.gz

cd haproxy-2.4.24

make TARGET=linux-glibc

make install

3. 查看版本,确认安装成功

haproxy -v

2.3.2 配置HAProxy(核心配置)

1. 创建配置文件目录和日志目录

mkdir -p /etc/haproxy

mkdir -p /var/log/haproxy

2. 编辑HAProxy配置文件

vim /etc/haproxy/haproxy.cfg

3. 写入以下配置(核心部分,其余可默认)

global

log 127.0.0.1 local0 info # 日志配置

maxconn 10000 # 最大连接数

daemon # 后台运行

defaults

log global

mode tcp # 模式为TCP(MySQL是TCP协议)

option tcplog # 开启TCP日志

option dontlognull

retries 3 # 连接失败重试次数

timeout connect 5000ms # 连接超时时间

timeout client 50000ms # 客户端超时时间

timeout server 50000ms # 服务器超时时间

MySQL负载均衡配置(frontend接收请求,backend分发请求)

frontend mysql_front

bind *:3306 # 监听3306端口(与MySQL端口一致,方便客户端访问)

default_backend mysql_back # 请求转发到mysql_back后端集群

backend mysql_back

balance roundrobin # 负载均衡算法:轮询(均匀分发请求)

option tcp-check # 开启TCP检测(检测MySQL节点是否存活)

tcp-check connect port 3306 # 检测3306端口

tcp-check send "SELECT 1\r\n" # 发送检测指令(MySQL心跳检测)

tcp-check expect string "1" # 期望返回结果,确认节点正常

配置两个MySQL主节点(weight是权重,默认1,可根据节点性能调整)

server mysql1 192.168.1.10:3306 check weight 1

server mysql2 192.168.1.11:3306 check weight 1

HAProxy监控页面(可选,便于查看集群状态)

listen stats

bind *:8888 # 监控页面端口

mode http

stats enable

stats uri /haproxy_stats # 监控页面路径

stats auth admin:admin # 监控页面用户名密码(可自定义)

2.3.3 启动HAProxy并设置开机自启

1. 启动HAProxy

haproxy -f /etc/haproxy/haproxy.cfg

2. 设置开机自启(创建系统服务)

vim /usr/lib/systemd/system/haproxy.service

写入以下内容:

Unit

Description=HAProxy Load Balancer

After=network.target

Service

ExecStart=/usr/local/sbin/haproxy -f /etc/haproxy/haproxy.cfg

ExecReload=/usr/local/sbin/haproxy -f /etc/haproxy/haproxy.cfg -s reload

ExecStop=/usr/local/sbin/haproxy -f /etc/haproxy/haproxy.cfg -s stop

Restart=on-failure

Install

WantedBy=multi-user.target

3. 启用并重启服务

systemctl daemon-reload

systemctl enable haproxy

systemctl restart haproxy

4. 验证HAProxy状态(确保启动成功)

systemctl status haproxy

2.4 安装配置Keepalived(虚拟IP漂移)

Keepalived的核心作用是实现虚拟IP(VIP)的漂移,为HAProxy节点提供高可用------当主HAProxy节点故障时,虚拟IP自动漂移到备用HAProxy节点,客户端无需修改连接地址,即可继续访问数据库服务,避免HAProxy成为单点故障。

2.4.1 安装Keepalived(所有HAProxy节点执行)

yum install -y keepalived

2.4.2 配置主HAProxy节点(192.168.1.12,MASTER角色)

1. 编辑Keepalived配置文件

vim /etc/keepalived/keepalived.conf

2. 写入以下配置(核心参数,替换对应IP)

! Configuration File for keepalived

global_defs {

router_id LVS_MASTER # 路由标识,主备节点需不同

}

检测HAProxy状态(核心:如果HAProxy停止,自动切换VIP)

vrrp_script chk_haproxy {

script "/etc/keepalived/check_haproxy.sh" # 检测脚本路径

interval 2 # 检测间隔(2秒)

weight -20 # 检测失败,权重降低20,触发切换

}

vrrp_instance VI_1 {

state MASTER # 角色:MASTER(主节点)

interface ens33 # 网卡名称(用ip addr查看自己的网卡,如eth0)

virtual_router_id 51 # 虚拟路由ID,主备节点必须一致(0-255)

priority 100 # 优先级,MASTER优先级高于BACKUP(如100>90)

advert_int 1 # 心跳发送间隔(1秒)

authentication {

auth_type PASS # 认证方式

auth_pass 1111 # 认证密码,主备节点必须一致

}

虚拟IP(VIP),客户端通过这个IP访问数据库,可设置多个

virtual_ipaddress {

192.168.1.200/24 # VIP地址,与服务器在同一网段

}

调用HAProxy检测脚本

track_script {

chk_haproxy

}

}

2.4.3 配置备HAProxy节点(192.168.1.13,BACKUP角色)

vim /etc/keepalived/keepalived.conf

配置与主节点基本一致,修改以下3处即可

! Configuration File for keepalived

global_defs {

router_id LVS_BACKUP # 路由标识,与主节点不同

}

vrrp_script chk_haproxy {

script "/etc/keepalived/check_haproxy.sh"

interval 2

weight -20

}

vrrp_instance VI_1 {

state BACKUP # 角色:BACKUP(备节点)

interface ens33 # 与主节点一致的网卡名称

virtual_router_id 51 # 与主节点一致

priority 90 # 优先级,低于主节点(90<100)

advert_int 1

authentication {

auth_type PASS

auth_pass 1111 # 与主节点一致

}

virtual_ipaddress {

192.168.1.200/24 # 与主节点一致的VIP

}

track_script {

chk_haproxy

}

}

2.4.4 创建HAProxy检测脚本(所有HAProxy节点执行)

脚本作用:定期检测HAProxy是否正常运行,若异常则停止Keepalived,触发VIP漂移。

1. 创建脚本文件

vim /etc/keepalived/check_haproxy.sh

2. 写入以下内容(检测HAProxy进程)

#!/bin/bash

检测HAProxy进程是否存在

if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then

若HAProxy未运行,停止Keepalived

systemctl stop keepalived

fi

3. 给脚本添加执行权限

chmod +x /etc/keepalived/check_haproxy.sh

2.4.5 启动Keepalived并设置开机自启

systemctl start keepalived

systemctl enable keepalived

查看Keepalived状态,确保启动成功

systemctl status keepalived

查看VIP是否生效(主节点会显示VIP,备节点不显示)

ip addr

2.5 集群整体测试(验证高可用)

测试1:负载均衡测试

客户端通过VIP(192.168.1.200)连接MySQL,多次插入数据,查看两个MySQL节点的日志,确认请求被HAProxy均匀分发(轮询模式)。

客户端连接MySQL(需安装MySQL客户端)

mysql -u root -pMySQL@123456 -h 192.168.1.200 -P 3306

插入多条数据,分别在Master1和Master2上查看binlog,确认均有请求

show binary logs;

mysqlbinlog 文件名 | grep 'insert into user' # 查看插入记录

测试2:MySQL节点故障测试

停止Master1的MySQL服务,客户端继续通过VIP连接,插入数据,确认数据能正常写入Master2,HAProxy自动剔除故障节点,无服务中断。

停止Master1的MySQL

systemctl stop mysqld

客户端继续插入数据,确认正常

mysql -u root -pMySQL@123456 -h 192.168.1.200 -P 3306

use test_ha;

insert into user(name) values('test_fault');

commit;

启动Master1的MySQL,确认数据自动同步(主主复制生效)

systemctl start mysqld

select * from user; # 能查询到故障期间插入的数据

测试3:HAProxy节点故障测试

停止主HAProxy节点(192.168.1.12)的HAProxy服务,查看VIP是否漂移到备HAProxy节点(192.168.1.13),客户端继续连接VIP,确认服务正常。

停止主HAProxy

systemctl stop haproxy

查看备节点的IP,确认VIP(192.168.1.200)已漂移

ip addr

客户端连接VIP,确认正常访问

mysql -u root -pMySQL@123456 -h 192.168.1.200 -P 3306

三、核心协同机制(必掌握)

3.1 主主复制的协同逻辑

主主复制是整个高可用集群的基础,核心协同逻辑是"双向同步、互为备份":

  1. 两个MySQL节点(Master1、Master2)均开启binlog和GTID,彼此作为对方的从库,同步对方的事务。

  2. 当客户端通过HAProxy向其中一个节点写入数据时,该节点将事务写入自身binlog,另一节点通过IO线程读取该binlog,SQL线程重放事务,实现数据同步。

  3. 核心优势:无需手动切换主从,任何一个节点故障,另一个节点可直接接管服务,数据无丢失(RPO=0),为后续负载均衡和故障切换提供数据基础。

  4. 注意点:需确保两个节点的配置一致(如server-id、binlog格式),避免主键冲突(建议使用自增主键,设置不同的自增步长,如Master1步长2、起始1;Master2步长2、起始2)。

3.2 Keepalived虚拟IP漂移机制

Keepalived基于VRRP(虚拟路由冗余协议)实现VIP漂移,核心协同逻辑是"心跳检测、优先级切换":

  1. 主备HAProxy节点运行Keepalived,主节点(MASTER)优先级高于备节点(BACKUP),主节点定期向备节点发送心跳(advert_int=1秒)。

  2. 正常情况下,主节点持有VIP,客户端通过VIP访问HAProxy,再由HAProxy分发请求到MySQL节点。

  3. 当主HAProxy节点故障(如HAProxy停止、服务器宕机),备节点无法收到主节点的心跳,触发VRRP选举:备节点检测到主节点故障后,提升自身优先级,接管VIP,实现VIP漂移(漂移时间≤3秒)。

  4. 当主节点恢复正常后,由于其优先级高于备节点,会重新接管VIP,备节点释放VIP,恢复备用状态。

  5. 核心作用:屏蔽HAProxy的单点故障,客户端无需修改连接地址,即可实现无缝切换,保障访问连续性。

3.3 HAProxy负载均衡协同机制

HAProxy作为请求入口,核心协同逻辑是"请求分发、故障检测、负载分担",衔接客户端与MySQL节点:

  1. 客户端通过VIP连接HAProxy的3306端口(与MySQL端口一致),HAProxy接收请求后,根据负载均衡算法(本次用轮询),将请求分发到两个MySQL主节点。

  2. HAProxy通过TCP检测机制(tcp-check),定期向MySQL节点发送"SELECT 1"心跳请求,检测节点是否存活:若节点无响应(如MySQL停止),HAProxy自动将该节点从后端集群中剔除,不再分发请求;若节点恢复,自动重新加入集群。

  3. 协同Keepalived:HAProxy的状态由Keepalived检测(通过check_haproxy.sh脚本),若HAProxy故障,Keepalived触发VIP漂移,确保客户端请求始终能到达正常的HAProxy节点。

  4. 核心作用:实现请求的负载分担,避免单个MySQL节点压力过大;同时实现MySQL节点的故障自动剔除,提升集群的并发处理能力和可用性。

3.4 三者整体协同流程(完整链路)

客户端 → VIP(Keepalived管理) → HAProxy(负载均衡) → MySQL主主节点(数据同步),完整协同流程如下:

  1. 正常状态:Keepalived主节点持有VIP,HAProxy正常运行,客户端通过VIP连接HAProxy,HAProxy将请求轮询分发到Master1和Master2,两个节点双向同步数据,负载均衡且数据一致。

  2. MySQL节点故障:若Master1故障,HAProxy检测到节点异常,自动停止向Master1分发请求,所有请求转发到Master2;Master1恢复后,HAProxy重新将其加入集群,主主复制同步缺失数据,恢复负载均衡。

  3. HAProxy节点故障:若主HAProxy故障,Keepalived检测到HAProxy停止,触发VIP漂移到备HAProxy;客户端继续通过VIP连接,备HAProxy接管请求分发,服务无中断;主HAProxy恢复后,VIP漂移回主节点,恢复正常架构。

四、实战注意事项

  • MySQL配置:必须开启GTID和log_slave_updates,binlog格式设为ROW,避免主从不一致;主主复制需设置不同的server-id,防止冲突。

  • HAProxy配置:模式设为TCP(MySQL是TCP协议),开启TCP检测,确保能准确识别MySQL节点状态;负载均衡算法可根据业务调整(如leastconn:最少连接优先)。

  • Keepalived配置:主备节点的virtual_router_id和auth_pass必须一致,主节点优先级高于备节点;检测脚本需添加执行权限,确保能正常检测HAProxy状态。

  • 下载异常处理:MySQL repo源和HAProxy安装包的原下载链接可能出现"不支持该文件类型""网页解析失败"等报错,可更换对应软件的其他版本,或使用国内镜像源(如阿里云、华为云镜像)下载,避免影响搭建流程。

  • 生产优化:MySQL节点建议关闭查询缓存,开启并行复制;HAProxy和Keepalived节点可部署在不同机房,提升集群抗灾能力;定期备份数据,避免极端故障导致数据丢失。

  • 故障排查:若集群异常,优先查看HAProxy日志(/var/log/haproxy)、Keepalived日志(/var/log/messages)、MySQL日志(/var/log/mysqld.log),定位故障节点和原因。

相关推荐
dajun1811234562 小时前
信息系统运维管理全流程详解 在线画图工具绘制运维流程图表技巧
运维·数据库·信息可视化·流程图·旅游·论文笔记
流觞 无依2 小时前
SQLite数据库损坏修复指南——解决“database disk image is malformed”报错
jvm·数据库·sqlite
道清茗2 小时前
【MySQL知识点问答题】 安全与性能管理
数据库·mysql
2501_920627612 小时前
Flutter 框架跨平台鸿蒙开发 - 数据库学习助手
数据库·学习·flutter·华为·harmonyos
ZStack开发者社区2 小时前
阿里云 × ZStack:云端管得好,边端交付稳
数据库·边缘计算
TDengine (老段)2 小时前
TDengine IDMP 可视化 —— 趋势图
大数据·数据库·人工智能·物联网·时序数据库·tdengine·涛思数据
万邦科技Lafite2 小时前
淘宝关键词API接口获取分类商品信息指南
java·前端·数据库·开放api·淘宝开放平台
RisunJan2 小时前
Linux命令-mysqlshow(显示MySQL中数据库相关信息)
linux·数据库·mysql
Geoking.2 小时前
MySQL的HAVING:掌握分组过滤的高级用法(实战详解)
mysql