1. MySQL 主从复制
1.1 复制核心原理
MySQL 主从复制基于**二进制日志(binlog)**实现数据同步,涉及三个核心线程:
| 线程 | 所在节点 | 作用 |
|---|---|---|
| Binlog Dump Thread | 主库 | 将主库的 binlog 事件发送给从库 |
| I/O Thread | 从库 | 连接到主库,请求 binlog 并写入中继日志 |
| SQL Thread | 从库 | 从中继日志读取事件,在从库上重放执行 |
工作流程:主库将所有数据修改操作记录到二进制日志;从库 I/O 线程通过 TCP 连接获取主库的 binlog 并存储为中继日志(Relay Log);从库 SQL 线程解析中继日志中的事件,在本地数据库重现相同操作。
复制模式:MySQL 支持异步(默认)、半同步、全同步三种模式,实际生产中半同步复制应用最广,在性能和数据一致性之间取得较好平衡。
1.2 一主一从配置实战
一、环境准备
| 角色 | IP 地址 | 系统环境 | MySQL 版本 |
|---|---|---|---|
| 主库 Master | 192.168.1.10 | Rocky9 | MySQL 8.0 |
| 从库 Slave | 192.168.1.11 | Rocky9 | MySQL 8.0 |
检查清单:主从节点 MySQL 版本一致;3306 端口网络互通;服务器时间通过 NTP 同步。
二、主库配置
编辑 /etc/my.cnf:
ini
[mysqld]
server-id = 1 # 唯一标识符,集群内不可重复
log-bin = mysql-bin # 启用二进制日志
binlog-format = ROW # 推荐使用 ROW 格式,保证数据一致性
sync-binlog = 1 # 每次事务提交都同步到磁盘
expire-logs-days = 7 # 自动清理 7 天前的日志
binlog-row-image = FULL # 完整行镜像
参数说明:server-id 在整个复制集群中必须唯一;log-bin 指定二进制日志文件名前缀;binlog-format=ROW 记录每行的变更,数据一致性最高;sync-binlog=1 保证 binlog 可靠性。重启 MySQL:systemctl restart mysqld。
三、创建复制账号
登录主库 MySQL:
sql
CREATE USER 'repl'@'%' IDENTIFIED BY 'StrongPass@123';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
查看当前二进制日志位点:
sql
SHOW MASTER STATUS;
-- 记录 File 和 Position 值,例如 mysql-bin.000001 和 154
四、从库配置
编辑 /etc/my.cnf:
ini
[mysqld]
server-id = 2 # 从库唯一 ID,不能与主库重复
relay-log = mysql-relay-bin # 中继日志
read-only = 1 # 建议开启只读模式防止误操作
参数说明:从库必须设置与主库不同的 server-id;relay-log 指定中继日志位置;read-only=1 防止在从库误执行写操作。重启 MySQL:systemctl restart mysqld。
登录从库 MySQL,配置主库信息:
sql
CHANGE MASTER TO
MASTER_HOST = '192.168.1.10',
MASTER_USER = 'repl',
MASTER_PASSWORD = 'StrongPass@123',
MASTER_LOG_FILE = 'mysql-bin.000001',
MASTER_LOG_POS = 154;
START SLAVE;
验证复制状态:
sql
SHOW SLAVE STATUS\G
-- 检查 Slave_IO_Running 和 Slave_SQL_Running 是否为 Yes
1.3 一主多从配置实战
一主多从架构在标准一主一从的基础上,可通过增加从库节点实现读能力的线性扩展。适用于读多写少、数据安全性要求较高的场景,将读流量分散到多个从库,分担主库查询压力。常见搭配方案包括"一主多从 + 读写分离",配合中间件(如 MyCat、ProxySQL)或 Keepalived 提供故障切换与统一接入。
核心实现:在多个从库节点上重复执行"一主一从"的从库配置步骤即可。 具体操作如下:
环境准备:
| 角色 | IP 地址 | MySQL 版本 | server-id |
|---|---|---|---|
| Master | 192.168.1.10 | MySQL 8.0 | 1 |
| Slave1 | 192.168.1.11 | MySQL 8.0 | 2 |
| Slave2 | 192.168.1.12 | MySQL 8.0 | 3 |
步骤一:主库配置(与一主一从相同)
已配置好 master,且已创建 repl 账号(binlog 位点已知)。
步骤二:从库1配置(192.168.1.11)
在 Slave1 上配置 /etc/my.cnf,设置 server-id=2 并启用 read-only=1。重启服务后执行:
sql
CHANGE MASTER TO
MASTER_HOST = '192.168.1.10',
MASTER_USER = 'repl',
MASTER_PASSWORD = 'StrongPass@123',
MASTER_LOG_FILE = 'mysql-bin.000001',
MASTER_LOG_POS = 154;
START SLAVE;
SHOW SLAVE STATUS\G -- 验证 Slave_IO_Running 和 Slave_SQL_Running 是否为 Yes
步骤三:从库2配置(192.168.1.12)
在 Slave2 上配置 /etc/my.cnf,设置 server-id=3 并启用 read-only=1。重启服务后执行:
sql
CHANGE MASTER TO
MASTER_HOST = '192.168.1.10',
MASTER_USER = 'repl',
MASTER_PASSWORD = 'StrongPass@123',
MASTER_LOG_FILE = 'mysql-bin.000001',
MASTER_LOG_POS = 154;
START SLAVE;
SHOW SLAVE STATUS\G -- 验证复制状态
验证: 在主库创建新表或插入数据,检查 Slave1 和 Slave2 是否都能同步该数据。
1.4 级联复制配置实战
级联复制通过一个中间从库(级联服务器)同时作为主库的下级和下级从库的主库,适用于需要为特定从库或应用隔离主库变更影响的场景,例如让某个下游系统从级联服务器同步数据,而不直接连接主库。
拓扑结构: Master → Master-Slave(级联节点)→ Slave
环境准备:
| 角色 | IP 地址 | server-id |
|---|---|---|
| Master | 192.168.1.10 | 1 |
| Master-Slave(级联节点) | 192.168.1.11 | 2(开启 log-bin 和 log-slave-updates) |
| Slave | 192.168.1.12 | 3 |
步骤一:主库配置(192.168.1.10)
与一主一从配置相同:
ini
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW
创建 repl 账号,记录位点。
步骤二:级联节点配置(192.168.1.11)
编辑 /etc/my.cnf,关键是要开启 log-bin 和 log-slave-updates:
ini
[mysqld]
server-id = 2 # 级联节点的唯一 ID
log-bin = mysql-bin # 必须开启 binlog
log-slave-updates = 1 # 关键:将从主库同步的数据也写入本机的 binlog
read-only = 1
relay-log = mysql-relay-bin
log-slave-updates 的作用:让级联节点在应用主库的变更后,也将这些变更写入自己的 binlog,这样下级从库才能从级联节点上同步数据。重启 MySQL 后,将级联节点配置为 Master 的从库(与一主一从相同)。
步骤三:下级从库配置(192.168.1.12)
编辑 /etc/my.cnf:
ini
[mysqld]
server-id = 3
read-only = 1
重启 MySQL 后,将下级从库指向级联节点(192.168.1.11),而非直接指向主库:
sql
CHANGE MASTER TO
MASTER_HOST = '192.168.1.11',
MASTER_USER = 'repl',
MASTER_PASSWORD = 'StrongPass@123',
MASTER_LOG_FILE = 'mysql-bin.000001',
MASTER_LOG_POS = 154;
START SLAVE;
验证流程:
- 在主库(192.168.1.10)创建新表或插入数据
- 查看级联节点(192.168.1.11),数据应已同步
- 查看下级从库(192.168.1.12),数据也应已同步
常见问题 :复制中断可使用 STOP SLAVE; SET GLOBAL sql_slave_skip_counter = 1; START SLAVE; 跳过错误事件;延迟问题可通过启用并行复制(slave_parallel_workers=8)优化。
2. LVS 概述
2.1 LVS 概念
LVS(Linux Virtual Server,Linux 虚拟服务器)是由章文嵩博士于 1998 年开发的开源负载均衡解决方案,现已集成至 Linux 内核(通过 IPVS 模块实现),可在传输层(TCP/UDP)进行高性能流量分发。
核心架构由三部分组成:
- 负载调度器(Director):接收客户端请求的入口节点,运行 ipvs 服务
- 服务器池(Real Server,RS):实际处理请求的应用服务器集群
- 共享存储(可选):确保 RS 间数据一致性
LVS 工作在内核层,直接处理 IP 数据包,具有高性能、低延迟、高并发等优势。相比 Nginx、HAProxy 等应用层负载均衡器,LVS 不解析应用层协议,省去了用户态与内核态的切换开销,吞吐量可达 10Gbps+ 级别。
2.2 LVS 工作原理
终端用户访问 LVS 调度器的虚拟 IP(VIP),调度器根据预设的调度算法将请求分发至后端真实服务器(RS),所有 RS 提供一致的服务,整个集群对用户完全透明。
在数据包层面,LVS 通过修改 IP 层或链路层信息实现请求转发,根据不同的工作模式采用不同的包处理方式。
2.3 LVS 集群模式特性
LVS 的核心工作模式有三种:
| 模式 | 转发原理 | 拓扑要求 | 性能 | 适用场景 |
|---|---|---|---|---|
| NAT 模式 | 修改数据包的目标 IP 地址 | RS 可使用私有 IP;LVS 做网关 | 中等,LVS 需处理进出双向流量 | 内网环境、测试环境 |
| DR 模式 | 修改 MAC 地址 | RS 与 LVS 同网段;RS 需配置 VIP | 最高,LVS 仅处理入向请求 | 高并发、低延迟业务(电商、游戏等) |
| TUN 模式 | IP-in-IP 隧道封装 | RS 可跨网段部署 | 较高 | 跨地域/跨机房部署 |
NAT 模式:LVS 作为网关,通过修改数据包的源/目的 IP 实现转发,支持异构操作系统,无需修改 RS 配置,但所有流量需经 LVS 转发,扩展性受限。
DR 模式:LVS 与 RS 共享 VIP,通过修改 MAC 地址将请求直接路由至目标服务器,响应包绕过 LVS 直接返回客户端。需在 RS 上配置 arp_ignore=1 和 arp_announce=2 避免 ARP 冲突。DR 模式性能最优,适合金融、电商等高并发场景。
TUN 模式:LVS 将原始 IP 包封装在新的 IP 包中转发至后端服务器,RS 解封装后处理请求并直接响应客户端,适用于跨机房或广域网部署。
3. LVS 调度算法
LVS 的调度算法可分为静态调度 (基于预设规则)和动态调度(基于实时状态)两大类,共提供十种调度算法。
3.1 静态调度算法
| 算法 | 原理 | 适用场景 |
|---|---|---|
| RR(轮询) | 按顺序将请求依次分配给每台 RS,循环往复 | 服务器性能相近的同构集群 |
| WRR(加权轮询) | 为每台 RS 分配权重,权重高的接收更多请求 | 服务器性能存在差异的异构集群 |
| DH(目标地址哈希) | 基于目标 IP 的哈希值将请求定向到固定 RS | 内网服务定向,实现会话保持 |
| SH(源地址哈希) | 基于源 IP 的哈希值分配请求 | 企业内网多数据中心架构 |
RR 实现最简单,轮询分配负载,数学表达为:第 i 个请求分配至服务器 S_{(i mod n)+1}。
WRR 为性能更强的服务器分配更高权重,权重高的服务器获得更多请求。例如将核心服务器权重设为 3,普通服务器权重设为 1。
SH/DH 基于哈希将请求持久化绑定到特定服务器,适用于需要会话保持的场景,但服务器故障时会产生大量迁移。
3.2 动态调度算法
| 算法 | 原理 | 适用场景 |
|---|---|---|
| LC(最少连接) | 将新请求分配给当前活动连接数最少的 RS | 长连接服务 |
| WLC(加权最少连接) | 结合权重与连接数,分配至连接数/权重比值最小的 RS | 异构集群中的长连接业务 |
| SED(最短期望延迟) | 基于 WLC 的改进,加入权重计算 | 需要平衡延迟的场景 |
| NQ(永不排队) | SED 的变种,优先分配空闲服务器 | 空闲服务器较多的场景 |
| LBLC(基于局部性的最少连接) | 基于目标 IP 的最小连接,优先连接缓存命中目标 | 缓存集群 |
LC 将新请求分配至连接数最少的服务器,数学表达为:分配至 min(conn_count[i]) 的服务器。
WLC 在 LC 基础上加入权重计算:分配至 min(conn_count[i]/weight[i]) 的服务器。
3.3 算法选型建议
| 业务类型 | 推荐算法 | 原因 |
|---|---|---|
| 长连接服务 | WLC / SH | 动态感知负载或保持会话连续性 |
| 短连接服务 | RR / WRR | 简单高效,无需维护连接状态 |
| 异构集群 | WRR / WLC | 根据性能差异分配负载 |
| 会话保持要求 | SH / DH | 哈希绑定用户到固定服务器 |
4. LVS 配置文件详解
4.1 keepalived 配置文件结构
keepalived 的配置文件 /etc/keepalived/keepalived.conf 由多个配置块组成,每个块用 {} 界定。主要包含三大模块:
1. 全局定义块(global_defs)
conf
global_defs {
router_id LVS_DIRECTOR # 节点唯一标识,备机应改为不同的标识
lvs_id LVS_LOAD_BALANCER # LVS 标识
enable_script_security # 启用脚本安全检查
}
2. VRRP 实例配置块(vrrp_instance)
负责 VIP 的漂移管理,是 Keepalived 实现高可用的核心:
conf
vrrp_instance VI_1 {
state MASTER # 节点角色:MASTER(主)或 BACKUP(备)
interface eth0 # 绑定网卡接口
virtual_router_id 51 # 虚拟路由 ID,主备必须一致(范围 0-255)
priority 150 # 优先级,值越高越优先(MASTER 应高于 BACKUP)
advert_int 1 # VRRP 心跳广播间隔(秒),越小切换越快
authentication {
auth_type PASS # 认证类型:PASS(简单密码)或 AH
auth_pass 123456 # 认证密码,主备必须一致
}
virtual_ipaddress {
192.168.10.100/24 dev eth0 label eth0:1 # 浮动 VIP 及网卡别名
}
}
virtual_router_id:主备节点必须保持一致,用于区分不同的 VRRP 实例priority:MASTER 节点应配置更高优先级,如 150,BACKUP 为 100advert_int:心跳周期,值越小故障切换越快,但网络开销越大
3. 虚拟服务器配置块(virtual_server)
该模块是 Keepalived 与 LVS 深度整合的核心,所有 ipvsadm 命令功能均可通过此模块配置:
conf
virtual_server 192.168.10.100 80 { # VIP 和端口
delay_loop 6 # 健康检查间隔(秒)
lb_algo wrr # 负载均衡算法:rr/wrr/lc/wlc/lblc/sh/dh
lb_kind DR # 工作模式:NAT(-m)/ DR(-g)/ TUN(-i)
persistence_timeout 60 # 会话保持时间(秒)
protocol TCP # 协议类型:TCP 或 UDP
# Real Server 1 定义
real_server 10.0.0.11 80 {
weight 1 # RS 权重,值越高分配越多请求
inhibit_on_failure # 故障时标记为不可用
TCP_CHECK { # TCP 健康检查方式
connect_timeout 3 # 连接超时(秒)
nb_get_retry 3 # 重试次数
delay_before_retry 2 # 重试前延迟(秒)
connect_port 80 # 检查的目标端口
}
}
# Real Server 2 定义
real_server 10.0.0.12 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 2
connect_port 80
}
}
}
关键参数说明:
lb_algo:支持算法包括 rr(轮询)、wrr(加权轮询)、lc(最少连接)、wlc(加权最少连接)、lblc、sh(源哈希)、dh(目标哈希)persistence_timeout:设置后将同一源 IP 的请求始终转发到同一 RS,避免会话状态丢失health check:Keepalived 通过 MISC_CHECK、TCP_CHECK、HTTP_GET 等方式检测 RS 健康状态,自动剔除故障节点weight:结合 lb_algo 为 wrr/wlc 使用,权重越高分配越多请求
5. LVS 部署实战
5.1 NAT 模式案例
拓扑结构:
text
Client (外网) → LVS调度器(VIP:192.168.1.100/对外,私有IP:10.0.0.1)→ RS1(10.0.0.11:80)
→ RS2(10.0.0.12:80)
LVS 同时拥有外网 IP(VIP)和内网私有 IP。RS 网关需指向 LVS 的内网 IP,响应流量经 LVS 返回客户端。
步骤一:LVS 调度器配置
bash
# 开启 IP 转发(必须)
echo 1 > /proc/sys/net/ipv4/ip_forward
# 永久生效:编辑 /etc/sysctl.conf,设置 net.ipv4.ip_forward=1
# 然后执行 sysctl -p
# 添加虚拟服务和 Real Server(NAT 模式使用 -m 参数)
ipvsadm -A -t 192.168.1.100:80 -s rr
ipvsadm -a -t 192.168.1.100:80 -r 10.0.0.11:80 -m
ipvsadm -a -t 192.168.1.100:80 -r 10.0.0.12:80 -m
# 查看配置结果
ipvsadm -Ln
步骤二:Real Server 配置
bash
# 两台 RS 需将默认网关设置为 LVS 调度器的内网 IP
route add default gw 10.0.0.1
启动 RS 上的 Web 服务(如 Nginx),监听端口 80。
步骤三:验证
bash
curl http://192.168.1.100:80
# 多次执行,观察请求轮询分发到 RS1 和 RS2
5.2 DR 模式案例
拓扑结构:
text
Client → LVS调度器(VIP:192.168.1.100,DIP:192.168.1.1)→ RS1(192.168.1.11:80)→ 直接返回 Client
→ RS2(192.168.1.12:80)→ 直接返回 Client
要求 LVS 与 RS 处于同一网段,响应包不经过 LVS。
步骤一:LVS 调度器配置
bash
# 配置 VIP(不响应 ARP 的隐藏模式)
ip addr add 192.168.1.100/24 dev eth0 label eth0:0
# 开启 IP 转发
echo 1 > /proc/sys/net/ipv4/ip_forward
# 添加虚拟服务和 Real Server(DR 模式使用 -g 参数)
ipvsadm -A -t 192.168.1.100:80 -s wrr
ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.11:80 -g
ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.12:80 -g
ipvsadm -Ln
步骤二:Real Server 配置(关键)
每台 RS 需配置 VIP 到 loopback 接口,并抑制 ARP 响应:
bash
# 配置 VIP 到 lo:0 接口(避免 ARP 冲突)
ifconfig lo:0 192.168.1.100 netmask 255.255.255.255 broadcast 192.168.1.100 up
# 配置 ARP 抑制,避免 RS 响应 VIP 的 ARP 请求
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
# 永久配置:写入 /etc/sysctl.conf
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
步骤三:验证
bash
curl http://192.168.1.100:80
ipvsadm -L -n -c # 查看当前连接状态
6. Keepalived 安装与配置
6.1 安装
bash
# CentOS/RHEL
yum install -y keepalived ipvsadm
# Ubuntu/Debian
apt update && apt install -y keepalived ipvsadm
6.2 配置文件完整模板
/etc/keepalived/keepalived.conf 生产环境配置模板:
conf
# ==================== 全局定义块 ====================
global_defs {
router_id LVS_MASTER # 节点唯一标识,备机改为 LVS_BACKUP
lvs_id LVS_LOAD_BALANCER # LVS 标识
enable_script_security # 启用脚本安全检查
# 邮件通知配置(可选)
notification_email {
admin@example.com
}
notification_email_from keepalived@example.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
}
# ==================== VRRP 脚本检测(可选)====================
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2 # 检测间隔(秒)
weight -20 # 失败时优先级减20
fall 2 # 连续失败2次判定故障
rise 1 # 连续成功1次恢复
}
# ==================== VRRP 实例块 ====================
vrrp_instance VI_1 {
state MASTER # 主节点:MASTER;备节点:BACKUP
interface eth0 # 绑定的物理网卡
virtual_router_id 51 # 虚拟路由 ID,主备必须一致(0-255)
priority 150 # 优先级:MASTER 需高于 BACKUP
advert_int 1 # VRRP 心跳广播间隔(秒)
# 认证配置
authentication {
auth_type PASS
auth_pass 123456 # 密码,主备必须一致
}
# 虚拟 IP 地址(VIP)
virtual_ipaddress {
192.168.10.100/24 dev eth0 label eth0:1
# 可配置多个 VIP
# 192.168.10.200/24 dev eth0 label eth0:2
}
# 调用健康检查脚本
track_script {
chk_nginx
}
# 通知脚本
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
# ==================== 虚拟服务器块(LVS 配置)====================
virtual_server 192.168.10.100 80 {
delay_loop 6 # 健康检查间隔(秒)
lb_algo wrr # 调度算法:rr/wrr/lc/wlc/lblc/sh/dh
lb_kind DR # 工作模式:NAT(-m)/ DR(-g)/ TUN(-i)
persistence_timeout 60 # 会话保持时间(秒)
protocol TCP # 协议类型
# ==================== Real Server 1 ====================
real_server 10.0.0.11 80 {
weight 1 # 权重
inhibit_on_failure # 故障时标记不可用
TCP_CHECK { # TCP 健康检查
connect_timeout 3 # 连接超时(秒)
nb_get_retry 3 # 重试次数
delay_before_retry 2 # 重试前延迟(秒)
connect_port 80
}
}
# ==================== Real Server 2 ====================
real_server 10.0.0.12 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 2
connect_port 80
}
}
# HTTP 健康检查示例
# real_server 10.0.0.11 80 {
# weight 1
# HTTP_GET {
# url {
# path /health
# status_code 200
# }
# connect_timeout 3
# nb_get_retry 3
# delay_before_retry 2
# }
# }
}
6.3 启动与管理
bash
systemctl start keepalived
systemctl enable keepalived
systemctl status keepalived
# 查看 VIP 状态
ip addr show
# 查看 LVS 规则
ipvsadm -L -n
7. Keepalived + Nginx 高可用案例
场景:两台 Nginx 服务器(业务层),通过 Keepalived 实现高可用切换。
架构:
text
Client → VIP(192.168.10.100) → Nginx1(192.168.10.11,MASTER)
→ Nginx2(192.168.10.12,BACKUP)
步骤一:安装 Nginx
两台服务器安装 Nginx:
bash
yum install -y nginx
systemctl start nginx
步骤二:创建健康检查脚本
在 /etc/keepalived/check_nginx.sh 创建:
bash
#!/bin/bash
# 检查 Nginx 进程是否存在
if [ -f /var/run/nginx.pid ]; then
exit 0
else
exit 1
fi
bash
chmod +x /etc/keepalived/check_nginx.sh
步骤三:配置 Keepalived(仅 Nginx 高可用,不加载 LVS)
/etc/keepalived/keepalived.conf:
conf
global_defs {
router_id NGINX_MASTER # 备机改为 NGINX_BACKUP
}
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight -20
}
vrrp_instance VI_1 {
state MASTER # 备机改为 BACKUP
interface eth0
virtual_router_id 52
priority 150 # 备机设置较低的优先级,如 100
advert_int 1
authentication {
auth_type PASS
auth_pass nginx123
}
virtual_ipaddress {
192.168.10.100/24 dev eth0 # VIP
}
track_script {
chk_nginx # 关联健康检查脚本
}
# 通知脚本(可选)
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
步骤四:启动服务
bash
systemctl start keepalived
systemctl enable keepalived
步骤五:验证高可用
bash
# 主节点:确认 VIP 已绑定
ip addr show | grep 192.168.10.100
# 停止主节点的 Nginx 或 Keepalived
systemctl stop nginx
# 检查 VIP 是否漂移到备节点
# 在备节点执行:ip addr show | grep 192.168.10.100
8. Keepalived + HAProxy 高可用案例
场景:两台 HAProxy 负载均衡器,通过 Keepalived 实现高可用;HAProxy 将流量分发到后端 Web 服务器集群。
架构:
text
Client → VIP(192.168.10.100) → HAProxy1(192.168.10.11,MASTER) → Web 集群
→ HAProxy2(192.168.10.12,BACKUP) → Web 集群
步骤一:安装 HAProxy
两台服务器安装 HAProxy:
bash
yum install -y haproxy
步骤二:配置 HAProxy(两台相同)
/etc/haproxy/haproxy.cfg:
conf
global
log /dev/log local0
maxconn 4096
user haproxy
group haproxy
defaults
log global
mode http
option httplog
option dontlognull
retries 3
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
# 前端:接收来自 VIP 的请求
frontend http-in
bind *:80 # 监听所有接口的 80 端口
default_backend web_servers
# 后端:Web 服务器集群
backend web_servers
balance roundrobin # 轮询算法
option httpchk GET /health # 健康检查
server web1 192.168.10.21:80 check inter 2s rise 2 fall 3
server web2 192.168.10.22:80 check inter 2s rise 2 fall 3
# 统计页面(可选)
listen stats
bind *:8080
stats enable
stats uri /haproxy?stats
stats auth admin:admin
启动 HAProxy:
bash
systemctl start haproxy
systemctl enable haproxy
步骤三:配置 Keepalived(仅 HAProxy 高可用,不加载 LVS)
/etc/keepalived/keepalived.conf:
conf
global_defs {
router_id HAPROXY_MASTER # 备机改为 HAPROXY_BACKUP
}
vrrp_script chk_haproxy {
script "killall -0 haproxy" # 检查 haproxy 进程是否运行
interval 2
weight -20
}
vrrp_instance VI_1 {
state MASTER # 备机改为 BACKUP
interface eth0
virtual_router_id 53
priority 150 # 备机优先级 100
advert_int 1
authentication {
auth_type PASS
auth_pass haproxy123
}
virtual_ipaddress {
192.168.10.100/24 dev eth0 # VIP
}
track_script {
chk_haproxy
}
}
步骤四:启动服务
bash
systemctl start keepalived
systemctl enable keepalived
步骤五:验证高可用
bash
# 主节点:确认 VIP 绑定
ip addr show | grep 192.168.10.100
# 通过 VIP 访问 HAProxy 统计页面
curl http://192.168.10.100:8080/haproxy?stats
# 停止主节点的 HAProxy 进行故障模拟
systemctl stop haproxy
# 验证 VIP 是否漂移到备节点
# 在备节点检查:ip addr show | grep 192.168.10.100
# 重新启动主节点 HAProxy 后,VIP 会漂移回主节点
systemctl start haproxy
步骤六:整合 LVS(可选)
如需 LVS 提供四层负载均衡,在 Keepalived 配置中添加 virtual_server 块(参见第 6 节),将流量分发到两台 HAProxy 的 80 端口,形成 LVS(四层)+ HAProxy(七层)双层负载均衡架构。
总结
| 技术 | 核心功能 | 典型组合 |
|---|---|---|
| MySQL 复制 | 数据库读写分离、数据冗余、主从切换 | 一主多从 + 读写分离中间件 |
| LVS | 四层负载均衡,高性能流量分发 | LVS-DR + Keepalived |
| Keepalived | VRRP 实现 VIP 漂移,健康检查 | Keepalived + Nginx / HAProxy / LVS |
| HAProxy | 七层负载均衡,精细化的流量调度 | HAProxy + Keepalived |
通过以上技术组合,可以构建从数据库层到应用接入层的完整高可用、高性能架构。
9.面试高频模块:MySQL复制 + LVS负载均衡 + Keepalived高可用
一、MySQL 主从复制(高频)
1.1 MySQL 主从复制的原理是什么?有哪些线程参与?
答:主从复制基于**二进制日志(binlog)**实现异步数据传输。 三个核心线程:
- Binlog Dump Thread(主库):读取主库 binlog 事件并发送给从库。
- I/O Thread(从库):连接主库接收 binlog,写入本地的中继日志(relay log)。
- SQL Thread(从库):读取 relay log 中的事件并在从库上重放。
流程图简述:主库写 binlog → 从库 I/O 线程拉取 → 写入 relay log → SQL 线程重放。
1.2 主从复制有哪些常见模式?各有什么优缺点?
| 模式 | 特点 | 优点 | 缺点 |
|---|---|---|---|
| 异步复制(默认) | 主库不关心从库是否接收 | 性能最高 | 主库宕机可能丢数据 |
| 半同步复制 | 至少一个从库确认收到 binlog 才提交 | 数据一致性较好 | 性能略降,等待从库响应 |
| 全同步复制 | 所有从库都确认后才提交 | 数据零丢失 | 性能极差,几乎不用 |
| GTID 复制 | 基于全局事务 ID,自动定位位点 | 故障切换方便,无需找位置 | 对版本有要求 |
面试追问:你用过半同步吗?如何开启? 答:安装
semisync_master.so和semisync_slave.so,设置rpl_semi_sync_master_enabled=1。
1.3 怎么搭建一主一从?关键参数有哪些?
答:
- 主库开启 binlog,设置
server-id=1,log-bin=mysql-bin。 - 创建复制账号
repl并赋予REPLICATION SLAVE权限。 - 从库设置
server-id=2,relay-log=mysql-relay-bin,read-only=1。 - 从库执行
CHANGE MASTER TO指定主库 IP、账号、密码、日志文件和位置。 START SLAVE并检查SHOW SLAVE STATUS\G中Slave_IO_Running和Slave_SQL_Running均为 Yes。
1.4 主从延迟怎么产生?如何优化?
原因:
- 从库硬件差(IO/CPU 瓶颈)
- 主库大事务(如批量删除、大表 DDL)
- 从库有慢查询
- 网络延迟
优化方案:
- 使用
sync_binlog=1+innodb_flush_log_at_trx_commit=1保证主库不丢,但会增加延迟(可折中) - 从库开启并行复制:
slave_parallel_workers=8,slave_parallel_type=LOGICAL_CLOCK - 避免大事务,拆分 DML
- 将从库的
binlog_format设为 ROW,减少 SQL 级解析开销
1.5 主从复制中断了怎么处理?
常见排查流程:
- 查看
SHOW SLAVE STATUS中Last_Error字段,确定错误原因。 - 如果是由于主键冲突或数据不存在,可临时跳过:
STOP SLAVE; SET GLOBAL sql_slave_skip_counter = 1; START SLAVE;(慎用)
- 如果是 GTID 复制:
STOP SLAVE; SET GTID_NEXT='...'; BEGIN; COMMIT; SET GTID_NEXT='AUTOMATIC'; START SLAVE;
- 若无法跳过,建议重做从库:重新备份主库 → 恢复到从库 → 重新 CHANGE MASTER。
二、LVS(Linux Virtual Server)高频
2.1 LVS 是什么?工作在哪一层?
答:LVS 是 Linux 内核集成的四层(传输层)负载均衡器,基于 IPVS 模块实现。它在 TCP/UDP 级别分发流量,不解析应用层数据,因此性能极高,适合大并发场景。
2.2 LVS 有哪几种工作模式?简述区别。
| 模式 | 转发原理 | 是否改写 IP | 响应是否经过 LVS | 要求同网段 | 性能 |
|---|---|---|---|---|---|
| NAT | 修改目标 IP 地址 | 是(DNAT) | 是(进出都经 LVS) | 否(RS 可私有 IP) | 中 |
| DR | 修改目标 MAC 地址 | 否 | 否(RS 直接回客户端) | 是 | 最高 |
| TUN | IP 隧道封装 | 是(新增 IP 头) | 否 | 否(可跨机房) | 较高 |
场景推荐:
- 内网且对性能要求极高 → DR 模式
- RS 与 LVS 不在同一物理网络 → TUN 模式
- 简单测试且 RS 需要隐藏真实 IP → NAT 模式
2.3 LVS 的调度算法有哪些?分别适用什么场景?
静态算法:
- RR(轮询):同性能服务器,短连接。
- WRR(加权轮询):服务器性能差异大。
- SH(源地址哈希):会话保持(如需要将同一用户绑定到同一 RS)。
- DH(目标地址哈希):缓存场景(相同目标 IP 转发到同一缓存服务器)。
动态算法:
- LC(最少连接):长连接服务(如数据库连接、WebSocket)。
- WLC(加权最少连接):异构服务器下的长连接。
- SED / NQ:极少用,LC 的优化变种。
- LBLC:基于局部性的最少连接,适合缓存集群。
面试常问:你们项目中用的是哪种算法?为什么? 回答范例:我们用的是 WRR,因为后端服务器配置不完全相同(有 8C16G 和 4C8G),需要按权重分配;同时由于 HTTP 请求多为短连接,没有采用 LC。
2.4 LVS DR 模式为什么要配置 arp_ignore 和 arp_announce?怎么配?
答:因为 DR 模式下 RS 也配置了 VIP(绑定在 lo 上),如果不对 ARP 行为进行限制,RS 会对 VIP 的 ARP 请求做出响应,导致客户端直接访问 RS 而非 LVS。
配置(所有 RS 上执行):
bash
bash
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
含义:
arp_ignore=1:只回答目标 IP 是接收网卡本地地址的 ARP 请求。arp_announce=2:忽略 IP 包的源地址,选择最合适的本地地址发送 ARP 响应。
2.5 LVS 如何检查后端 RS 的健康状态?
答 :LVS 本身不具备健康检查功能,通常结合 Keepalived 实现。Keepalived 通过 virtual_server 块中的 TCP_CHECK 或 HTTP_GET 定期探测 RS,若失败则自动从 LVS 规则中移除该 RS。 另外也可使用 ipvsadm 手动添加/删除 RS,或配合 noquorum 服务做外部检测。
三、Keepalived 高频
3.1 Keepalived 是什么?核心原理是什么?
答 :Keepalived 是一个高可用解决方案,核心基于 VRRP(虚拟路由冗余协议)实现。它通过竞选机制决定 MASTER 和 BACKUP 节点,MASTER 持有虚拟 IP(VIP),BACKUP 监听 MASTER 的心跳,当 MASTER 故障时,BACKUP 自动接管 VIP。同时 Keepalived 集成了对 LVS 的管理和健康检查。
3.2 VRRP 协议中 MASTER 和 BACKUP 是如何选出来的?
答:
- 每个节点配置
priority(范围 0-255),优先级高者成为 MASTER。 - MASTER 会定期发送 VRRP 广告(
advert_int间隔),BACKUP 在master_down_interval时间内未收到广告则主动抢占。 - 若设置
nopreempt可关闭抢占模式。
3.3 Keepalived 如何实现业务进程的联动(比如 Nginx 挂了自动切换)?
答 :通过 vrrp_script 定义自定义检测脚本,例如:
bash
vrrp_script check_nginx {
script "/usr/bin/killall -0 nginx"
interval 2
weight -20
}
然后在 vrrp_instance 中通过 track_script 引用。当脚本返回值非 0(表示 Nginx 故障),Keepalived 会将本机优先级减少 weight 值,若优先级低于 BACKUP 则触发 VIP 漂移。
3.4 你配置过 Keepalived + Nginx 高可用吗?配置文件要点有哪些?
答:配置过。核心要点:
- 两台服务器安装 Nginx 和 Keepalived。
- 主节点
state MASTER,priority 150;备节点state BACKUP,priority 100。 - 设置相同的
virtual_router_id、auth_pass。 - 配置
virtual_ipaddress为 VIP(如 192.168.10.100/24)。 - 定义健康检查脚本,检测 Nginx 进程,并关联
track_script。 - 启动后通过
ip addr show验证 VIP 是否在主节点上;停止主节点 Nginx 验证漂移。
3.5 Keepalived + HAProxy 与 + LVS 的区别?各自场景?
| 组合 | 作用层次 | 适用场景 |
|---|---|---|
| Keepalived + LVS | 四层负载均衡 + 高可用 | 需要极高吞吐量、简单分发(如数据库、redis 集群) |
| Keepalived + HAProxy | 七层负载均衡 + 高可用 | 需要 URL 路由、SSL 卸载、高级健康检查(如 Web、API 网关) |
| Keepalived + Nginx | 七层高可用(Nginx 自身做反向代理) | 轻量级、Nginx 已作为 Web 服务器或反向代理 |
面试官可能会追问:能同时用 LVS + HAProxy 吗? 答:可以,典型架构是 LVS(四层)→ HAProxy(七层)→ 应用服务器。LVS 做入口流量均衡,HAProxy 实现内容路由。
四、综合场景题(重点考察解决思路)
4.1 如果一个 LVS DR 模式下,客户端访问 VIP 不通,可能的原因有哪些?
排查思路:
- 检查 LVS 主机上
ipvsadm -L -n是否有对应的 VIP 和 RS 规则。 - 检查 LVS 主机上 VIP 是否已正确配置在网卡上(
ip addr)。 - 检查 RS 上是否配置了 VIP(
lo:0)且 arp 参数正确。 - 检查 RS 的 Web 服务是否监听正确端口,并可通过 DIP 直接访问。
- 网络层面:RS 网关是否指向 LVS(DR 模式不需要),是否在同一广播域。
- 查看 LVS 统计信息
ipvsadm -L -n -c是否有连接记录。
4.2 你设计过 MySQL 高可用方案吗?结合 LVS/Keepalived 如何做?
答:常见方案:
- LVS + Keepalived 做 MySQL 读负载均衡:多台从库配置为 LVS 的 RS,VIP 提供统一读入口。缺点是不支持读写分离,需业务层判断。
- MHA / MGR + Keepalived:MySQL 主库故障时自动选举新主,Keepalived 负责 VIP 漂移,让业务快速切换到新主。
- ProxySQL + Keepalived:ProxySQL 自带读写分离,两台 ProxySQL 通过 Keepalived 提供 VIP 高可用。
面试中可回答:我们的业务是读多写少,使用 LVS + Keepalived 将多台从库做负载均衡,主库单独用 Keepalived 做高可用(VIP + MHA)。
4.3 请描述一个完整的 LVS + Keepalived + Nginx + MySQL 高可用 Web 架构。
参考答案:
- 前端:Keepalived 提供 VIP(如 10.0.0.100),两台 LVS(DR 模式)做四层负载均衡。
- 中间层:LVS 将流量分发到多台 Nginx(七层反向代理)。
- 应用层:Nginx 将动态请求转发到 PHP-FPM 或 Tomcat 集群。
- 数据层:MySQL 主从复制 + Keepalived(VIP 指向主库),从库通过 LVS 提供读负载均衡。 整个架构无单点,任意一层故障自动切换。
五、快速记忆口诀
- MySQL 复制三线程:主库 Binlog Dump,从库 I/O 和 SQL。
- LVS 三大模式:NAT 改 IP,DR 改 MAC,TUN 套隧道。
- 调度算法记七种:RR、WRR、LC、WLC、SH、DH、LBLC。
- Keepalived 三核心:VRRP 抢 VIP,脚本检健康,规则配 LVS。
六、高频配置题
题目:写一个 Keepalived + LVS(DR 模式)的配置片段,要求 VIP 为 192.168.1.200,后端两台 RS(192.168.1.11:80,192.168.1.12:80),算法为 wrr,权重分别为 3 和 1,健康检查方式为 TCP 端口检测。
答案(节选):
conf
virtual_server 192.168.1.200 80 {
delay_loop 6
lb_algo wrr
lb_kind DR
persistence_timeout 60
protocol TCP
real_server 192.168.1.11 80 {
weight 3
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 2
connect_port 80
}
}
real_server 192.168.1.12 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 2
connect_port 80
}
}
}
附加:RS 上需要配置
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore等命令并绑定 VIP 到 lo:0。