Keepalived + LVS(DR)+ MariaDB 主主高可用架构实战指南
从单点故障到 99.99% 可用性,一套方案搞定数据库读写分离、负载均衡与自动故障转移
一、为什么需要这套架构?
在企业级应用中,数据库是业务数据的"核心载体"。无论是电商交易、金融支付还是政务系统,都对数据库提出以下刚性需求:
- 24×7 无间断服务:避免单点故障导致业务中断。秒杀活动中,数据库宕机 1 分钟可能造成数万元损失。
- 高并发读写:日均 SQL 从百万到亿级,单机 CPU/IO 瓶颈明显。
- 数据零丢失:硬件故障或软件异常时,数据不损坏、不丢失。
- 灵活扩展:读压力增大时可快速新增节点,无需修改业务代码。
传统架构的痛点
| 架构 | 问题 |
|---|---|
| 单节点数据库 | 单点故障致命,MTTR 通常超 30 分钟 |
| 简单主从(一主一从) | 写瓶颈仍在主库,主库故障需手动切换,易出错 |
| 业务层硬编码读写分离 | 无故障检测,扩展需重启服务,运维复杂 |
二、方案选型:为什么是 Keepalived + LVS + MariaDB 主主?
| 组件 | 作用 | 核心优势 |
|---|---|---|
| MariaDB 主主 | 双主互备,同时处理写请求 | 写性能翻倍(500 TPS → 1000+ TPS),任一节点故障无数据丢失 |
| LVS(DR 模式) | 四层负载均衡,分发读写请求 | 单机 10 万+ 并发连接,响应直返客户端,效率极高 |
| Keepalived | LVS 主备高可用(VRRP) | 故障时 1~3 秒自动切换 VIP,消除负载均衡层单点风险 |
预期收益:
- 可用性从 99.9% 提升至 99.99%(年中断时间从 8.76 小时降至 52 分钟)
- 写性能 1000+ TPS,95% 查询响应 < 200ms
- 故障自动转移,运维效率提升 70%
三、MariaDB 主从复制原理(主主的基础)
主从复制是主主同步的基石,核心流程如下:
- 主库 将数据变更写入 binlog(二进制日志)
- 从库 IO 线程连接主库,请求指定位置后的 binlog
- 主库 binlogdump 线程将增量 binlog 传输给从库
- 从库 IO 线程将收到的内容写入本地 relay log(中继日志)
- 从库 SQL 线程读取 relay log 并重放,实现数据一致
主主复制:只需将"主库"和"从库"角色互换,再执行一次主从配置即可。
四、实验环境
| 主机名 | IP 地址 | 角色 |
|---|---|---|
| client1.wzh.cloud | 10.1.8.21 | 客户端(测试) |
| router.wzh.cloud | 10.1.8.20 / 10.1.1.20 | 路由器(跨网段) |
| ha1.wzh.cloud | 10.1.8.13 | LVS + Keepalived(主) |
| ha2.wzh.cloud | 10.1.8.14 | LVS + Keepalived(备) |
| db1.wzh.cloud | 10.1.8.11 | MariaDB 主主节点1 |
| db2.wzh.cloud | 10.1.8.12 | MariaDB 主主节点2 |
VIP :10.1.8.100/24(由 Keepalived 管理)
所有节点操作系统为 CentOS 7 / RHEL 系,网卡为 ens33。
五、基础配置(主机名 & 网络)
以下为各节点的关键配置(以 db1 为例,其余类似):
bash
bash
# db1
hostnamectl set-hostname db1.wzh.cloud
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.11/24 \
ipv4.gateway 10.1.8.20 ipv4.dns 223.5.5.5 autoconnect yes
nmcli connection up ens33
路由器配置(开启转发和 NAT):
bash
bash
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf && sysctl -p
systemctl enable firewalld --now
firewall-cmd --set-default-zone=trusted
firewall-cmd --add-masquerade --permanent && firewall-cmd --reload
六、MariaDB 主主搭建
6.1 安装并初始化(db1 和 db2)
bash
bash
yum install -y mariadb-server
编辑 /etc/my.cnf.d/server.cnf,在 [mysqld] 段添加:
db1 配置:
ini
server-id = 1
log_bin = mysql-bin
relay_log = mysql-relay-bin
db2 配置:
ini
server-id = 2
log_bin = mysql-bin
relay_log = mysql-relay-bin
启动服务并安全初始化(设置 root 密码为 huawei,删除匿名用户、禁止远程 root 登录、删除 test 库):
bash
bash
systemctl enable mariadb --now
mysql_secure_installation # 按提示操作
6.2 配置主从:db2 → db1(即 db1 为主,db2 为从)
在主库 db1 上:
sql
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'10.1.8.12' IDENTIFIED BY 'huawei';
FLUSH PRIVILEGES;
SHOW MASTER STATUS\G
-- 记录 File 和 Position,例如 mysql-bin.000003, Position=327
在从库 db2 上:
sql
CHANGE MASTER TO
MASTER_HOST='10.1.8.11',
MASTER_USER='repl',
MASTER_PASSWORD='huawei',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=327,
MASTER_CONNECT_RETRY=30;
START SLAVE;
SHOW SLAVE STATUS\G -- 确保 Slave_IO_Running 和 Slave_SQL_Running 均为 Yes
6.3 配置主从:db1 → db2(反向同步,实现主主)
在主库 db2 上(此时角色互换):
sql
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'10.1.8.11' IDENTIFIED BY 'huawei';
FLUSH PRIVILEGES;
SHOW MASTER STATUS\G -- 记录新 File 和 Position
在从库 db1 上:
sql
CHANGE MASTER TO
MASTER_HOST='10.1.8.12',
MASTER_USER='repl',
MASTER_PASSWORD='huawei',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000002', -- 以实际为准
MASTER_LOG_POS=1769,
MASTER_CONNECT_RETRY=30;
START SLAVE;
SHOW SLAVE STATUS\G -- 同样检查两个 Yes
验证:在 db1 创建库,db2 自动同步;在 db2 创建表,db1 也能看到。
七、配置 LVS + Keepalived(高可用负载均衡)
7.1 后端 RS(db1/db2)配置 VIP 环回口及 ARP 参数
所有数据库节点(db1, db2)执行:
bash
bash
# 创建 dummy 网卡绑定 VIP(仅用于响应,不对外宣告)
nmcli connection add type dummy ifname dummy con-name dummy ipv4.method manual ipv4.addresses 10.1.8.100/32
nmcli connection up dummy
# 调整 ARP 参数,避免 VIP 冲突
cat >> /etc/sysctl.conf << EOF
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.dummy.arp_ignore = 1
net.ipv4.conf.dummy.arp_announce = 2
EOF
sysctl -p
7.2 安装 Keepalived 和 ipvsadm(ha1 和 ha2)
bash
bash
yum install -y keepalived ipvsadm
cp /etc/keepalived/keepalived.conf{,.bak}
主 LVS(ha1) 的 /etc/keepalived/keepalived.conf:
nginx
! Configuration File for keepalived
global_defs {
router_id ha1
}
vrrp_instance db {
state MASTER
interface ens33
virtual_router_id 51
priority 110
advert_int 1
authentication {
auth_type PASS
auth_pass wzh@123
}
virtual_ipaddress {
10.1.8.100/24
}
}
virtual_server 10.1.8.100 3306 {
delay_loop 6
lb_algo rr
lb_kind DR
persistence_timeout 50
protocol TCP
real_server 10.1.8.11 3306 {
weight 1
TCP_CHECK {
connect_timeout 3
retry 3
delay_before_retry 3
}
}
real_server 10.1.8.12 3306 {
weight 2
TCP_CHECK {
connect_timeout 3
retry 3
delay_before_retry 3
}
}
}
备 LVS(ha2) 只需将 state MASTER 改为 state BACKUP,priority 改为 100(低于主),其余相同。
启动服务:
bash
bash
systemctl enable keepalived --now
八、功能测试
8.1 创建测试账号(在任意主库执行)
sql
GRANT ALL PRIVILEGES ON *.* TO 'wzh'@'%' IDENTIFIED BY 'huawei';
FLUSH PRIVILEGES;
8.2 客户端连接测试
在 client1 安装 mysql 客户端:
bash
bash
yum install -y mysql
mysql -uwzh -phuawei -h 10.1.8.100
成功连接即表示 LVS 正常分发请求。
8.3 高可用测试
-
停止 ha1 上的 keepalived:
bash
bashsystemctl stop keepalived此时 VIP 应在 1~3 秒内漂移至 ha2,客户端连接仍正常。
-
停止 db1 上的 mariadb:
bash
bashsystemctl stop mariadbLVS 健康检查会剔除 db1,所有请求自动转发到 db2,业务不受影响。
-
恢复服务,再次连接验证。
九、总结与运维建议
- 双主写入 :注意避免自增主键冲突,可设置
auto_increment_increment=2和auto_increment_offset分别为 1 和 2。 - 监控:建议配合 Prometheus + Grafana 监控 LVS 连接数、MariaDB 复制延迟、VIP 状态。
- 备份:尽管有双主,仍需定期全量备份(如 mysqldump 或 xtrabackup)。
- 扩展:若读压力继续增大,可添加多个只读从库并配置 LVS 转发读请求(需区分读写端口或使用不同 VIP)。