文章目录
- [Keepalived + LVS(DR) + MariaDB主主 小白完整实战教程](#Keepalived + LVS(DR) + MariaDB主主 小白完整实战教程)
-
- 一、业务背景与架构选型
- 二、MariaDB主从/主主复制原理
- 三、实验环境规划
- 四、基础环境初始化(所有机器)
-
- [1. 修改主机名、网卡IP](#1. 修改主机名、网卡IP)
- [2. router路由器开启IP转发](#2. router路由器开启IP转发)
- 五、部署MariaDB,配置主主双向复制
- 六、数据库后端RS配置LVS‑DR环境(db1、db2两台都操作)
- 七、Keepalived+LVS配置调度器ha1、ha2
-
- [ha1(主调度器,priority 110)](#ha1(主调度器,priority 110))
- [ha2(备调度器,priority 100)](#ha2(备调度器,priority 100))
- 八、业务测试验证
-
- [1. 在数据库创建远程测试账号(db1执行即可,主主会同步到db2)](#1. 在数据库创建远程测试账号(db1执行即可,主主会同步到db2))
- [2. client客户端安装mysql客户端工具访问VIP](#2. client客户端安装mysql客户端工具访问VIP)
- 故障模拟测试(核心高可用验证)
- 九、常见踩坑排错清单
Keepalived + LVS(DR) + MariaDB主主 小白完整实战教程
整套架构:四层负载均衡LVS‑DR + Keepalived实现调度器主备高可用 + MariaDB双主互备复制,实现数据库无间断对外服务,企业常用数据库高可用方案。 整体流程:客户端连接VIP访问数据库 → Keepalived+LVS做四层调度,分发请求到两台MariaDB;数据库双向主主复制保证两边数据一致;任意一台调度器/数据库故障自动切换,业务无感知。
一、业务背景与架构选型
数据库业务四大刚性需求
- 高可用(24×7不间断):硬件宕机、进程崩溃不能导致业务中断,故障自动转移。
- 高并发承载:读写量大,单台数据库CPU/IO容易瓶颈。
- 数据可靠性:故障不丢失数据,多节点之间数据同步一致。
- 可扩展:增加数据库节点不用修改业务代码。
传统架构痛点
| 架构 | 问题 |
|---|---|
| 单节点数据库 | 单点故障,宕机业务全部中断,恢复慢,有丢数据风险 |
| 简单一主一从 | 写操作全部压在主库;故障切换需要人工操作,容易出错 |
| 业务层硬编码地址 | 没有故障检测,后端宕机业务还会继续访问故障节点;新增节点需要改代码重启服务 |
本套方案组件分工
| 组件 | 作用 |
|---|---|
| MariaDB主主复制 | 两台数据库互为主从,双向binlog同步;两台库都可以读写,一台故障另一台拥有完整数据 |
| LVS‑DR四层负载均衡 | 转发数据库3306端口请求;响应报文数据库直接返回客户端,不经过调度器,性能极高;自带后端节点健康检测,故障节点自动剔除 |
| Keepalived | 1. 给LVS做主备高可用,VIP故障漂移,消除调度器单点;2. 直接写配置生成ipvs规则,不用敲命令;3. TCP健康检查后端数据库3306端口,数据库挂掉自动摘除节点 |
项目预期收益
- 可用性提升,故障自动切换无需人工干预;
- 写能力双库分担,读能力可以继续追加从库横向扩展;
- 业务只需要连接一个VIP地址,后端数据库变更业务代码零修改。
二、MariaDB主从/主主复制原理
主主复制本质就是两台数据库互做对方的主从复制,A同步B,B同步A,实现双向数据同步。
核心日志与线程
- binlog二进制日志(主库):记录所有增删改DDL/DML语句,是复制的数据源。
- relay log中继日志(从库):从库拉取到binlog先存成本地中继日志,再执行。
- binlog dump线程(主库):把binlog事件发送给从库IO线程。
- IO线程(从库):连接主库,拉取binlog,写入relay‑log。
- SQL线程(从库):读取relay‑log,在本机回放SQL实现数据同步。
完整同步流程
- 主库执行写操作,事务提交,写入binlog日志。
- 从库IO线程连接主库,指定binlog文件名和position位置请求日志。
- 主库dump线程读取binlog,把事件传给从库IO线程。
- IO线程收到数据写入本机relay‑log,记录同步位点。
- SQL线程读取relay‑log,回放SQL语句,完成数据同步。
主主复制:db1→db2做一遍主从;db2→db1再反向做一遍主从,双向同步。
三、实验环境规划
| 主机名 | IP地址 | 网关 | 角色 | VIP |
|---|---|---|---|---|
| client2.meng.cloud | 10.1.1.21 | 10.1.1.20 | 外部测试客户端 | 无 |
| client1.meng.cloud | 10.1.8.21 | 10.1.8.20 | 内网测试客户端 | 无 |
| router.meng.cloud | 10.1.8.20 / 10.1.1.20 | 10.1.8.2 | 路由器 | 无 |
| ha1.meng.cloud | 10.1.8.13 | 10.1.8.20 | LVS+Keepalived主调度器 | 10.1.8.100 |
| ha2.meng.cloud | 10.1.8.14 | 10.1.8.20 | LVS+Keepalived备调度器 | 10.1.8.100 |
| db1.meng.cloud | 10.1.8.11 | 10.1.8.20 | MariaDB数据库1 | 10.1.8.100(dummy网卡) |
| db2.meng.cloud | 10.1.8.12 | 10.1.8.20 | MariaDB数据库2 | 10.1.8.100(dummy网卡) |
VIP统一:
10.1.8.100,业务客户端只连接这个IP访问数据库3306端口。
四、基础环境初始化(所有机器)
1. 修改主机名、网卡IP
#### client2
hostnamectl set-hostname client2.meng.cloud
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.1.21/24 ipv4.gateway 10.1.1.20 ipv4.dns 223.5.5.5 autoconnect yes
nmcli connection up ens33
#### client1
hostnamectl set-hostname client1.meng.cloud
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.21/24 ipv4.gateway 10.1.8.20 ipv4.dns 223.5.5.5 autoconnect yes
nmcli connection up ens33
#### router路由器
hostnamectl set-hostname router.meng.cloud
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.20/24 ipv4.gateway 10.1.8.2 ipv4.dns 223.5.5.5 autoconnect yes
nmcli connection up ens33
nmcli connection add type ethernet con-name ens36 ifname ens36 ipv4.method manual ipv4.addresses 10.1.1.20/24 autoconnect yes
nmcli connection up ens36
#### ha1调度器
hostnamectl set-hostname ha1.meng.cloud
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.13/24 ipv4.gateway 10.1.8.20 ipv4.dns 223.5.5.5 autoconnect yes
nmcli connection up ens33
#### ha2调度器
hostnamectl set-hostname ha2.meng.cloud
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.14/24 ipv4.gateway 10.1.8.20 ipv4.dns 223.5.5.5 autoconnect yes
nmcli connection up ens33
#### db1数据库
hostnamectl set-hostname db1.meng.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
#### db2数据库
hostnamectl set-hostname db2.meng.cloud
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.12/24 ipv4.gateway 10.1.8.20 ipv4.dns 223.5.5.5 autoconnect yes
nmcli connection up ens33
2. router路由器开启IP转发
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
systemctl enable --now firewalld
firewall-cmd --set-default-zone=trusted
firewall-cmd --add-masquerade --permanent
firewall-cmd --add-masquerade
五、部署MariaDB,配置主主双向复制
db1配置
-
安装服务,开启binlog、relay‑log
yum install -y mariadb-server
vim /etc/my.cnf.d/server.cnf
写入mysqld段落:
[mysqld]
server-id=1
log_bin=mysql-bin
relay_log=mysql-relay-bin
启动服务:
systemctl enable --now mariadb
-
安全初始化(设置root密码
huawei,移除匿名用户等)mysql_secure_installation
交互步骤:回车(旧密码为空) → Y设置密码,输入
huawei,确认;后面全部回车确认。
-
创建复制账号,授权给db2
mysql -uroot -phuawei
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配置
-
安装,配置my.cnf,server‑id必须不一样!db2写2
yum install -y mariadb-server
vim /etc/my.cnf.d/server.cnf
[mysqld]
server-id=2
log_bin=mysql-bin
relay_log=mysql-relay-bin
systemctl enable --now mariadb
mysql_secure_installation -
创建复制账号授权给db1
mysql -uroot -phuawei
grant replication slave, replication client on . to 'repl'@'10.1.8.11' identified by 'huawei';
flush privileges;
show master status\G;
记录File、Position示例:mysql‑bin.000002,Position:1769
第一步:db2作为从库,同步db1(db1→db2)
db2数据库执行mysql命令,替换成刚刚show master status拿到的文件名和position
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: Yes、Slave_SQL_Running: Yes才算正常。
测试:db1建库建表插入数据,db2查询,确认数据同步过来。
第二步:db1作为从库,同步db2(db2→db1,完成双向主主)
db1数据库执行,替换db2的binlog文件名和position
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;
✅db1这边也必须IO、SQL线程全部Yes;双向复制完成,两边写数据都可以互相同步。
⚠️主主复制注意:业务层要做好主键冲突规避,否则双向同时插入相同主键会报错。
六、数据库后端RS配置LVS‑DR环境(db1、db2两台都操作)
DR模式关键点:后端数据库也要绑定VIP/32掩码;ARP抑制,不对外响应VIP的ARP请求,防止ARP漂移。
# 创建dummy虚拟网卡,绑定VIP,掩码32位!!
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抑制内核参数
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
参数解释:
arp_ignore=1:只接收本机真实网卡IP的ARP请求,dummy上的VIP不回复ARP;arp_announce=2:发送ARP广播不用VIP做源IP,避免把VIP‑MAC广播出去造成冲突。
七、Keepalived+LVS配置调度器ha1、ha2
Keepalived的
virtual_server段直接生成ipvs规则;TCP_CHECK每隔一段时间探测3306端口,数据库端口不通自动把该RS剔除负载均衡集群。
ha1(主调度器,priority 110)
安装软件
yum install -y keepalived ipvsadm
cp /etc/keepalived/keepalived.conf{,.bak}
vim /etc/keepalived/keepalived.conf
完整配置文件
! 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 meng@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 1
TCP_CHECK {
connect_timeout 3
retry 3
delay_before_retry 3
}
}
}
启动服务
systemctl enable --now keepalived
ipvsadm -Ln
ip addr
ha2(备调度器,priority 100)
yum install -y keepalived ipvsadm
cp /etc/keepalived/keepalived.conf{,.bak}
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id ha2
}
vrrp_instance db {
state BACKUP
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass meng@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 1
TCP_CHECK {
connect_timeout 3
retry 3
delay_before_retry 3
}
}
}
systemctl enable --now keepalived
参数说明 virtual_server:
delay_loop 6:每6秒执行一次后端TCP健康检查;lb_algo rr:轮询调度算法;lb_kind DR:LVS DR模式;persistence_timeout 50:会话保持50秒,同一个客户端50秒内分配到同一台后端;TCP_CHECK:探测3306端口,端口访问失败,自动从ipvs集群移除该real_server。
重要提醒:real_server后面只能写IP,不支持域名,LVS四层工作,不做域名解析,填域名直接启动报错。
八、业务测试验证
1. 在数据库创建远程测试账号(db1执行即可,主主会同步到db2)
mysql -uroot -phuawei
grant ALL PRIVILEGES on *.* to 'meng'@'%' identified by 'huawei';
flush privileges;
2. client客户端安装mysql客户端工具访问VIP
yum install -y mysql
# 访问VIP,不需要写db1/db2真实IP
mysql -umeng -phuawei -h 10.1.8.100
故障模拟测试(核心高可用验证)
- 调度器故障测试 :ha1执行
systemctl stop keepalived,观察VIP漂移到ha2,客户端依然可以正常连接数据库。恢复ha1 keepalived,VIP切回ha1。 - 数据库节点故障测试 :db1执行
systemctl stop mariadb;keepalived检测3306端口不通,自动将db1剔除集群;客户端访问VIP只会调度到db2,业务不中断;启动db1数据库,自动重新加入集群。 - 双向复制验证:db1新建库表插入数据,db2查询看是否同步;db2插入数据,db1查询看是否同步。
九、常见踩坑排错清单
- LVS‑DR访问不通
- db1/db2是否配置dummy网卡VIP掩码
/32; - arp_ignore / arp_announce内核参数是否生效;
- 所有机器必须在同一个二层广播域,DR模式依靠MAC转发,跨VLAN不行。
- db1/db2是否配置dummy网卡VIP掩码
- MariaDB主主不同步
- server‑id两台数据库不能相同;
- repl复制账号授权IP是否正确,密码一致;
show slave status\G看IO/SQL线程状态,Last_IO_Error、Last_SQL_Error查看报错。
- Keepalived脑裂(两台调度器同时拿到VIP)
- 防火墙放行VRRP协议:
firewall‑cmd --add‑protocol=vrrp --permanent; - vrrp实例
virtual_router_id两台必须一致,auth_pass密码两台必须一模一样; - 多网卡机器使用
mcast_src_ip指定心跳报文发出网卡IP。
- 防火墙放行VRRP协议:
- keepalived启动失败
- virtual_server、real_server语法不能写错,大括号配对,不能使用域名写后端地址。
- 主主复制业务坑:应用层尽量规避两台库同时生成自增主键,否则主键冲突复制报错;生产建议配合中间件(ProxySQL)做读写分离。
制账号授权IP是否正确,密码一致;
show slave status\G看IO/SQL线程状态,Last_IO_Error、Last_SQL_Error查看报错。
- Keepalived脑裂(两台调度器同时拿到VIP)
- 防火墙放行VRRP协议:
firewall‑cmd --add‑protocol=vrrp --permanent; - vrrp实例
virtual_router_id两台必须一致,auth_pass密码两台必须一模一样; - 多网卡机器使用
mcast_src_ip指定心跳报文发出网卡IP。
- 防火墙放行VRRP协议:
- keepalived启动失败
- virtual_server、real_server语法不能写错,大括号配对,不能使用域名写后端地址。
- 主主复制业务坑:应用层尽量规避两台库同时生成自增主键,否则主键冲突复制报错;生产建议配合中间件(ProxySQL)做读写分离。