Linux高可用与负载均衡技术栈指南

18 阅读27分钟

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 版本
主库 Master192.168.1.10Rocky9MySQL 8.0
从库 Slave192.168.1.11Rocky9MySQL 8.0

检查清单:主从节点 MySQL 版本一致;3306 端口网络互通;服务器时间通过 NTP 同步。

二、主库配置

编辑 /etc/my.cnf

[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:

CREATE USER 'repl'@'%' IDENTIFIED BY 'StrongPass@123';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

查看当前二进制日志位点:

SHOW MASTER STATUS;
-- 记录 File 和 Position 值,例如 mysql-bin.000001 和 154

四、从库配置

编辑 /etc/my.cnf

[mysqld]
server-id = 2                           # 从库唯一 ID,不能与主库重复
relay-log = mysql-relay-bin             # 中继日志
read-only = 1                           # 建议开启只读模式防止误操作

参数说明:从库必须设置与主库不同的 server-idrelay-log 指定中继日志位置;read-only=1 防止在从库误执行写操作。重启 MySQL:systemctl restart mysqld

登录从库 MySQL,配置主库信息:

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

1.3 一主多从配置实战

一主多从架构在标准一主一从的基础上,可通过增加从库节点实现读能力的线性扩展。适用于读多写少、数据安全性要求较高的场景,将读流量分散到多个从库,分担主库查询压力。常见搭配方案包括“一主多从 + 读写分离”,配合中间件(如 MyCat、ProxySQL)或 Keepalived 提供故障切换与统一接入。

核心实现:在多个从库节点上重复执行“一主一从”的从库配置步骤即可。 具体操作如下:

环境准备:

角色IP 地址MySQL 版本server-id
Master192.168.1.10MySQL 8.01
Slave1192.168.1.11MySQL 8.02
Slave2192.168.1.12MySQL 8.03

步骤一:主库配置(与一主一从相同)

已配置好 master,且已创建 repl 账号(binlog 位点已知)。

步骤二:从库1配置(192.168.1.11)

在 Slave1 上配置 /etc/my.cnf,设置 server-id=2 并启用 read-only=1。重启服务后执行:

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。重启服务后执行:

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
Master192.168.1.101
Master-Slave(级联节点)192.168.1.112(开启 log-bin 和 log-slave-updates)
Slave192.168.1.123

步骤一:主库配置(192.168.1.10)

与一主一从配置相同:

[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW

创建 repl 账号,记录位点。

步骤二:级联节点配置(192.168.1.11)

编辑 /etc/my.cnf,关键是要开启 log-binlog-slave-updates

[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

[mysqld]
server-id = 3
read-only = 1

重启 MySQL 后,将下级从库指向级联节点(192.168.1.11),而非直接指向主库:

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;

验证流程:

  1. 在主库(192.168.1.10)创建新表或插入数据
  2. 查看级联节点(192.168.1.11),数据应已同步
  3. 查看下级从库(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)

global_defs {
    router_id LVS_DIRECTOR          # 节点唯一标识,备机应改为不同的标识
    lvs_id LVS_LOAD_BALANCER        # LVS 标识
    enable_script_security          # 启用脚本安全检查
}

2. VRRP 实例配置块(vrrp_instance)

负责 VIP 的漂移管理,是 Keepalived 实现高可用的核心:

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 为 100
  • advert_int:心跳周期,值越小故障切换越快,但网络开销越大

3. 虚拟服务器配置块(virtual_server)

该模块是 Keepalived 与 LVS 深度整合的核心,所有 ipvsadm 命令功能均可通过此模块配置:

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 模式案例

拓扑结构

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 调度器配置

# 开启 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 配置

# 两台 RS 需将默认网关设置为 LVS 调度器的内网 IP
route add default gw 10.0.0.1

启动 RS 上的 Web 服务(如 Nginx),监听端口 80。

步骤三:验证

curl http://192.168.1.100:80
# 多次执行,观察请求轮询分发到 RS1 和 RS2

5.2 DR 模式案例

拓扑结构

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 调度器配置

# 配置 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 响应:

# 配置 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

步骤三:验证

curl http://192.168.1.100:80
ipvsadm -L -n -c    # 查看当前连接状态

6. Keepalived 安装与配置

6.1 安装

# CentOS/RHEL
yum install -y keepalived ipvsadm

# Ubuntu/Debian
apt update && apt install -y keepalived ipvsadm

6.2 配置文件完整模板

/etc/keepalived/keepalived.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 启动与管理

systemctl start keepalived
systemctl enable keepalived
systemctl status keepalived

# 查看 VIP 状态
ip addr show
# 查看 LVS 规则
ipvsadm -L -n

7. Keepalived + Nginx 高可用案例

场景:两台 Nginx 服务器(业务层),通过 Keepalived 实现高可用切换。

架构

Client → VIP(192.168.10.100) → Nginx1(192.168.10.11,MASTER)
                            → Nginx2(192.168.10.12,BACKUP)

步骤一:安装 Nginx

两台服务器安装 Nginx:

yum install -y nginx
systemctl start nginx

步骤二:创建健康检查脚本

/etc/keepalived/check_nginx.sh 创建:

#!/bin/bash
# 检查 Nginx 进程是否存在
if [ -f /var/run/nginx.pid ]; then
    exit 0
else
    exit 1
fi
chmod +x /etc/keepalived/check_nginx.sh

步骤三:配置 Keepalived(仅 Nginx 高可用,不加载 LVS)

/etc/keepalived/keepalived.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"
}

步骤四:启动服务

systemctl start keepalived
systemctl enable keepalived

步骤五:验证高可用

# 主节点:确认 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 服务器集群。

架构

Client → VIP(192.168.10.100) → HAProxy1(192.168.10.11,MASTER) → Web 集群
                            → HAProxy2(192.168.10.12,BACKUP) → Web 集群

步骤一:安装 HAProxy

两台服务器安装 HAProxy:

yum install -y haproxy

步骤二:配置 HAProxy(两台相同)

/etc/haproxy/haproxy.cfg

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:

systemctl start haproxy
systemctl enable haproxy

步骤三:配置 Keepalived(仅 HAProxy 高可用,不加载 LVS)

/etc/keepalived/keepalived.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
    }
}

步骤四:启动服务

systemctl start keepalived
systemctl enable keepalived

步骤五:验证高可用

# 主节点:确认 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
KeepalivedVRRP 实现 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.sosemisync_slave.so,设置 rpl_semi_sync_master_enabled=1

1.3 怎么搭建一主一从?关键参数有哪些?

  1. 主库开启 binlog,设置 server-id=1log-bin=mysql-bin
  2. 创建复制账号 repl 并赋予 REPLICATION SLAVE 权限。
  3. 从库设置 server-id=2relay-log=mysql-relay-binread-only=1
  4. 从库执行 CHANGE MASTER TO 指定主库 IP、账号、密码、日志文件和位置。
  5. START SLAVE 并检查 SHOW SLAVE STATUS\GSlave_IO_RunningSlave_SQL_Running 均为 Yes。

1.4 主从延迟怎么产生?如何优化?

原因

  • 从库硬件差(IO/CPU 瓶颈)
  • 主库大事务(如批量删除、大表 DDL)
  • 从库有慢查询
  • 网络延迟

优化方案

  • 使用 sync_binlog=1 + innodb_flush_log_at_trx_commit=1 保证主库不丢,但会增加延迟(可折中)
  • 从库开启并行复制:slave_parallel_workers=8slave_parallel_type=LOGICAL_CLOCK
  • 避免大事务,拆分 DML
  • 将从库的 binlog_format 设为 ROW,减少 SQL 级解析开销

1.5 主从复制中断了怎么处理?

常见排查流程

  1. 查看 SHOW SLAVE STATUSLast_Error 字段,确定错误原因。
  2. 如果是由于主键冲突或数据不存在,可临时跳过:
    • STOP SLAVE; SET GLOBAL sql_slave_skip_counter = 1; START SLAVE; (慎用)
  3. 如果是 GTID 复制:
    • STOP SLAVE; SET GTID_NEXT='...'; BEGIN; COMMIT; SET GTID_NEXT='AUTOMATIC'; START SLAVE;
  4. 若无法跳过,建议重做从库:重新备份主库 → 恢复到从库 → 重新 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 直接回客户端)最高
TUNIP 隧道封装是(新增 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

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_CHECKHTTP_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 定义自定义检测脚本,例如:

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 高可用吗?配置文件要点有哪些?

:配置过。核心要点:

  1. 两台服务器安装 Nginx 和 Keepalived。
  2. 主节点 state MASTERpriority 150;备节点 state BACKUPpriority 100
  3. 设置相同的 virtual_router_idauth_pass
  4. 配置 virtual_ipaddress 为 VIP(如 192.168.10.100/24)。
  5. 定义健康检查脚本,检测 Nginx 进程,并关联 track_script
  6. 启动后通过 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 不通,可能的原因有哪些?

排查思路

  1. 检查 LVS 主机上 ipvsadm -L -n 是否有对应的 VIP 和 RS 规则。
  2. 检查 LVS 主机上 VIP 是否已正确配置在网卡上(ip addr)。
  3. 检查 RS 上是否配置了 VIP(lo:0)且 arp 参数正确。
  4. 检查 RS 的 Web 服务是否监听正确端口,并可通过 DIP 直接访问。
  5. 网络层面:RS 网关是否指向 LVS(DR 模式不需要),是否在同一广播域。
  6. 查看 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 端口检测。

答案(节选):

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。