Patroni + HAProxy + Keepalived + watchdog + ETCD PostgreSQL 高可用集群架构分析

一、背景与目标

1. 项目背景

A. 业务场景

PostgreSQL 作为主流开源关系型数据库,在企业核心业务系统中扮演着关键角色。传统单节点部署存在单点故障风险,主从复制方案在主节点故障时需要手动切换,影响业务连续性。

B. 痛点分析

  • 单点故障:主节点宕机导致服务中断
  • 手动切换:故障恢复需要人工介入,耗时长
  • 脑裂风险:网络分区可能导致多主节点
  • 数据一致性问题:主备切换时数据可能丢失

2. 设计目标

A. 功能目标

  • 实现自动故障检测与切换
  • 保障数据一致性和完整性
  • 提供读写分离能力

B. 非功能目标

  • 高可用性:99.99% 以上
  • 故障切换时间:毫秒级
  • 业务无感知:透明切换
  • 防止脑裂:分布式共识保障

二、总体架构

1. 设计原则

  • 分层架构:客户端应用层、负载均衡层、数据库集群层、分布式一致性层
  • 自动化运维:故障自动检测、自动切换、自动恢复
  • 防止脑裂:基于分布式共识的选举机制
  • 读写分离:智能路由优化性能

2. 系统架构

graph TB
    Client[客户端应用层] --> VIP[虚拟 IP 192.168.231.140]
    VIP -->|VRRP 协议| Keep1[Keepalived Master]
    VIP -->|VRRP 协议| Keep2[Keepalived Backup]
    Keep1 --> HA1[HAProxy 主节点]
    Keep2 --> HA2[HAProxy 备节点]
    HA1 -->|读写分离| Patroni1[Patroni Leader]
    HA1 -->|只读| Patroni2[Patroni Follower]
    HA1 -->|只读| Patroni3[Patroni Follower]
    HA2 --> Patroni1
    HA2 --> Patroni2
    HA2 --> Patroni3
    Patroni1 --> PG1[(PostgreSQL 主节点)]
    Patroni2 --> PG2[(PostgreSQL 备节点)]
    Patroni3 --> PG3[(PostgreSQL 备节点)]
    Patroni1 -.分布式共识.-> ETCD1[(ETCD 节点 1)]
    Patroni2 -.分布式共识.-> ETCD2[(ETCD 节点 2)]
    Patroni3 -.分布式共识.-> ETCD3[(ETCD 节点 3)]
    WD1[Watchdog 监控] -.心跳检测.-> Patroni1
    WD2[Watchdog 监控] -.心跳检测.-> Patroni2
    WD3[Watchdog 监控] -.心跳检测.-> Patroni3

mermaid

PostgreSQL 高可用集群整体架构

3. 组件说明

  • 客户端应用层:业务系统通过统一 VIP 访问,对底层架构无感知
  • 负载均衡层:HAProxy + Keepalived 实现智能路由和负载均衡层高可用
  • 数据库集群层:PostgreSQL + Patroni 实现数据高可用和自动故障转移
  • 分布式一致性层:ETCD 集群提供强一致性保障,防止脑裂
  • 进程监控层:Watchdog 监控 Patroni 进程状态,异常时强制重启

三、负载均衡层设计

1. HAProxy 组件

A. 组件职责

HAProxy(High Availability Proxy)是开源高性能代理软件,在架构中负责:

  • 接收客户端连接请求
  • 根据 PostgreSQL 节点角色进行读写分离路由
  • 执行健康检查,自动剔除故障节点
  • 实现负载均衡,优化资源利用

B. 核心架构

graph LR
    Client[客户端请求] --> Frontend[Frontend 前端处理]
    Frontend --> LB[Load Balancer 负载均衡]
    LB --> Backend[Backend 后端管理]
    Backend --> HC[Health Checker 健康检查]
    Backend --> CM[Connection Manager 连接管理]
    Backend --> Server1[(PostgreSQL 主节点)]
    Backend --> Server2[(PostgreSQL 备节点 1)]
    Backend --> Server3[(PostgreSQL 备节点 2)]
    HC -->|健康检查| Server1
    HC -->|健康检查| Server2
    HC -->|健康检查| Server3
    CM --> SE[Statistics Engine 统计引擎]

mermaid

HAProxy 核心架构

C. 请求处理流程

sequenceDiagram
    participant C as 客户端
    participant H as HAProxy
    participant P as Patroni/PostgreSQL

    C->>H: 1. 发起连接
    H->>H: 2. Accept Connection
    H->>H: 3. Parse Request
    H->>H: 4. Route Request
    H->>H: 5. Select Server(读写分离)
    H->>P: 6. Connect to Server
    P-->>H: 7. Connection Established
    C->>H: 8. Proxy Traffic
    H->>P: 9. Forward Request
    P-->>H: 10. Response
    H-->>C: 11. Process Response
    H->>C: 12. Close Connection

mermaid

HAProxy 请求处理流程

D. 健康检查配置

default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions

inter 3s              # 健康检查间隔 3 秒
fall 3               # 连续 3 次失败标记为 down
rise 2               # 连续 2 次成功标记为 up
option pgsql-check   # PostgreSQL 专用健康检查
timeout connect 5s   # 连接超时 5 秒
timeout server 30s   # 服务器响应超时 30 秒

mermaid

E. 负载均衡算法

  • Round Robin:轮询算法,默认方式
  • Least Connections:最少连接算法
  • Source IP Hashing:源 IP 哈希算法
  • URI Hashing:URI 哈希算法

F. 健康检查类型

  • TCP Check:TCP 端口连通性检查
  • HTTP Check:HTTP 请求和响应检查
  • SSL Check:SSL 证书和连接检查
  • PostgreSQL Check:PostgreSQL 数据库检查

2. Keepalived 组件

A. 组件职责

Keepalived 通过 VRRP 协议实现虚拟 IP 高可用,为 HAProxy 主备节点提供心跳检测与故障切换,确保负载均衡层无单点故障。

B. 核心架构

graph TB
    VRRP[VRRP 模块] -->|心跳广播| Master[主节点 Priority 100]
    VRRP -->|心跳广播| Backup[备节点 Priority 90]
    Master -->|持有 VIP| VIP[虚拟 IP 192.168.231.140]
    Backup -->|待机| VIP
    HC[健康检查模块] -->|监控 HAProxy| Master
    HC -->|监控 HAProxy| Backup
    HC -->|优先级调整| VRRP
    SE[脚本执行器] -->|chk_haproxy.sh| HC
    NS[通知系统] -->|状态变化告警| VRRP
    IPVS[IPVS 集成] -->|负载均衡| VRRP

mermaid

Keepalived 核心架构

C. VRRP 状态转换

stateDiagram-v2
    [*] --> INIT: 系统启动
    INIT --> BACKUP: 初始化完成
    BACKUP --> MASTER: 收到更高优先级广告<br/>或选举超时
    MASTER --> BACKUP: 收到更高优先级广告
    MASTER --> FAULT: 健康检查失败
    BACKUP --> FAULT: 健康检查失败
    FAULT --> BACKUP: 故障恢复

mermaid

Keepalived VRRP 状态转换

D. 配置示例

vrrp_instance VI_1 {
    state MASTER              # 主节点 MASTER,备节点 BACKUP
    interface eth0            # 网络接口
    virtual_router_id 51      # 虚拟路由 ID
    priority 100              # 主节点优先级 100,备节点 90
    advert_int 1              # VRRP 心跳广播间隔 1 秒
    authentication {
        auth_type PASS
        auth_pass 62f7f8e5
    }
    virtual_ipaddress {
        192.168.231.140/24    # 虚拟 IP 地址
    }
}

vrrp_script chk_haproxy {
    script "/check/haproxy.sh"
    interval 3                # 检查间隔 3 秒
    timeout 2                 # 超时时间 2 秒
    rise 2                    # 成功阈值 2 次
    fall 3                    # 失败阈值 3 次
    weight -30                # 优先级调整权重
}

E. 故障处理机制

  • 主节点故障:自动选举新主节点,VIP 无缝转移
  • 健康检查失败:优先级自动调整,触发状态切换
  • 服务恢复:自动回到正常状态,重新参与选举

四、分布式一致性层设计

1. ETCD 组件

A. 组件职责

ETCD 是基于 Raft 协议的分布式键值存储,为 Patroni 集群提供强一致性的状态存储与共识服务:

  • 记录数据库节点角色信息
  • 存储 Leader 选举信息
  • 维护集群配置数据
  • 保障 Leader 选举唯一性,防止脑裂

B. 核心架构

graph TB
    Client[Patroni 客户端] --> API[API Server]
    API --> Raft[Raft 一致性模块]
    Raft --> Log[日志存储]
    Raft --> Snapshot[快照存储]
    Raft --> WAL[WAL 预写日志]
    Log --> Store[(键值存储)]
    Snapshot --> Store
    WAL --> Store
    Raft -->|心跳广播| Node1[ETCD 节点 1]
    Raft -->|心跳广播| Node2[ETCD 节点 2]
    Raft -->|心跳广播| Node3[ETCD 节点 3]

mermaid

ETCD 核心架构

C. Raft 选举流程

sequenceDiagram
    participant F1 as Follower 节点 1
    participant F2 as Follower 节点 2
    participant F3 as Follower 节点 3
    participant L as Leader

    Note over F1,F3: Step 1: Follower State<br/>等待 Leader 心跳
    F3->>F3: Election Timeout 超时

    Note over F1,F3: Step 2: Election Timeout<br/>触发选举
    F3->>F3: 转换为 Candidate State

    Note over F1,F3: Step 3: Candidate State<br/>增加任期,发起投票
    F3->>F1: RequestVote (任期 N)
    F3->>F2: RequestVote (任期 N)

    Note over F1,F3: Step 4: Vote Collection<br/>收集投票
    F1-->>F3: 投票同意
    F2-->>F3: 投票同意

    Note over F1,F3: Step 5: Leader Election<br/>获得多数票成为 Leader
    F3->>F3: 成为 Leader

    Note over F1,F3: Step 6: Leader State<br/>发送心跳维持权威
    F3->>F1: AppendEntries 心跳
    F3->>F2: AppendEntries 心跳

mermaid

ETCD Raft 选举流程

D. 选举参数配置

--heartbeat-interval=100ms        # Leader 心跳间隔
--election-timeout=1000ms         # 选举超时时间
--min-election-timeout=1000ms     # 最小选举超时
--max-election-timeout=2000ms     # 最大选举超时
--initial-election-tick-advance=true  # 初始选举优化

五、进程监控层设计

1. Watchdog 组件

A. 组件职责

Watchdog 通过接收 Patroni 的定时心跳来监控其运行状态:

  • 监控 Patroni 进程健康状态
  • 检测进程假死或心跳超时
  • 触发服务或系统重启
  • 防止故障节点导致脑裂

B. 核心架构

graph TB
    Patroni[Patroni 进程] -->|每 10 秒心跳| WD[Watchdog 监控器]
    WD -->|心跳超时 30 秒| Systemd[Systemd 服务管理器]
    Systemd -->|重启服务| Patroni
    WD -->|最后手段| Kernel[Linux Kernel Watchdog]
    Kernel -->|强制重启| System

mermaid

Watchdog 核心架构

C. 配置示例

# Watchdog 配置
watchdog:
  mode: automatic
  safety_margin: 5      # 安全裕度 5 秒
  interval: 10          # 心跳间隔 10 秒
  timeout: 30           # 超时时间 30 秒

# Systemd 服务配置
[Service]
WatchdogSec=30s         # 看门狗超时 30 秒
Restart=on-failure      # 失败时重启
RestartSec=1s           # 重启间隔 1 秒
StartLimitBurst=3       # 启动限制次数
StartLimitInterval=60s  # 启动限制时间窗口

D. 故障场景处理

  • 脑裂问题:多个主节点同时存在
  • 进程假死:Patroni 进程存在但无响应
  • 网络分区:节点与 ETCD 集群隔离
  • 资源耗尽:CPU、内存或磁盘资源不足

E. 恢复处理流程

graph TB
    Start[故障检测] --> Check{心跳超时?}
    Check -->|是| Alert[告警通知]
    Check -->|否| Monitor[继续监控]
    Alert --> Restart[服务重启]
    Restart --> Success{恢复成功?}
    Success -->|是| Verify[恢复验证]
    Success -->|否| SystemReboot[系统重启]
    SystemReboot --> Verify
    Verify --> End[恢复完成]
    Monitor --> Start

mermaid

Watchdog 恢复处理流程

F. 防止脑裂机制

  • 心跳超时检测:30 秒内未收到心跳触发告警
  • 自动重启机制:防止故障节点继续写入数据
  • 集群状态验证:与 ETCD 集群状态对比
  • 数据一致性检查:验证 WAL 日志位置

六、数据库集群层设计

1. Patroni 组件

A. 组件职责

Patroni 是 PostgreSQL 高可用架构的核心管家:

  • 实现自动化的主备选举
  • 执行故障检测与故障转移
  • 实时监控数据库状态
  • 维护集群配置一致性
  • 协调主备节点的流复制同步
  • 对接 HAProxy 实现流量智能路由

B. 核心架构

graph TB
    EM[Election Manager 选举管理器] -->|状态转换| HM[Health Monitor 健康监控器]
    HM -->|节点状态检测| PG[PostgreSQL 数据库]
    EM -->|分布式共识| EC[ETCD Client]
    EC -->|存储/读取状态| ETCD[(ETCD 集群)]
    PG -->|角色信息| HM
    HM -->|健康检查| EM
    EM -->|REST API| API[REST API 接口]
    API -->|状态查询| Monitor[监控系统]
    API -->|手动干预| Admin[管理员]

mermaid

Patroni 核心架构

C. 选举状态流程

stateDiagram-v2
    [*] --> INIT: 系统初始化
    INIT --> FOLLOWER: 加入集群
    FOLLOWER --> CANDIDATE: Leader 故障检测
    CANDIDATE --> LEADER: 获得多数票
    CANDIDATE --> FOLLOWER: 未获得多数票
    LEADER --> DEMOTED: 主动降级或故障
    DEMOTED --> FOLLOWER: 降级完成
    LEADER --> FOLLOWER: 重新选举

mermaid

Patroni 选举状态流程

D. 选举流程详解

sequenceDiagram
    participant F1 as Follower 节点 1
    participant F2 as Follower 节点 2
    participant F3 as Follower 节点 3
    participant E as ETCD 集群
    participant PG as PostgreSQL

    Note over F1,F3: 故障检测
    F1->>E: 检测 Leader 心跳超时
    F2->>E: 检测 Leader 心跳超时

    Note over F1,F3: 触发选举
    F1->>F1: 转换为 CANDIDATE
    F1->>E: 请求投票
    F2->>E: 投票给 F1

    Note over F1,F3: 收集选票
    E-->>F1: 获得多数票
    F1->>F1: 成为 Leader

    Note over F1,F3: 提升 PostgreSQL
    F1->>PG: 提升为主节点
    PG-->>F1: 提升成功

    Note over F1,F3: 通知集群
    F1->>E: 更新集群状态
    E-->>F2: 新 Leader 通知
    E-->>F3: 新 Leader 通知

mermaid

Patroni 选举流程详解

E. 配置示例

dcs:
  ttl: 30                           # Leader 租约超时时间 30 秒
  loop_wait: 10                     # 心跳发送间隔 10 秒
  retry_timeout: 10                 # 重试超时时间 10 秒
  maximum_lag_on_failover: 1048576  # 最大复制延迟 1MB

election:
  retry_timeout: 10                 # 选举重试超时 10 秒
  maximum_retry_timeout: 30         # 最大选举重试超时 30 秒
  retry_interval: 2                 # 选举重试间隔 2 秒
  priority: 100                     # 节点优先级

F. 防止脑裂机制

  • ETCD 共识保障:使用分布式锁和租约机制
  • 多数票原则:必须获得集群多数节点的支持
  • 自动降级机制:故障节点自动降级避免数据不一致

七、技术选型

1. 技术栈对比

组件层次技术选型替代方案选择理由
负载均衡HAProxyNginx、LVS性能优秀、PostgreSQL 专用健康检查
VIP 高可用KeepalivedHeartbeat轻量级、配置简单、VRRP 标准
分布式共识ETCDConsul、ZooKeeperRaft 协议、强一致性、Go 语言高性能
数据库高可用PatroniRePM、PgpoolPython 开发、社区活跃、功能完善
进程监控WatchdogMonit系统级保障、硬件级重启能力

2. 性能指标

  • 故障检测时间:10-30 秒
  • 故障切换时间:毫秒级
  • 数据零丢失:基于同步复制
  • 支持 5 万+ QPS

八、高可用机制分析

1. 多层级高可用保障

graph TB
    subgraph 第一层
        VIP[虚拟 IP] --> Keep[Keepalived 主备]
    end

    subgraph 第二层
        Keep --> HA[HAProxy 负载均衡]
    end

    subgraph 第三层
        HA --> Pat[Patroni 集群]
    end

    subgraph 第四层
        Pat --> PG[PostgreSQL 主备]
    end

    subgraph 第五层
        Pat --> ETCD[ETCD 共识]
        WD[Watchdog] -.监控.-> Pat
    end

mermaid

多层级高可用保障

2. 故障场景处理

故障类型检测方式恢复机制恢复时间
HAProxy 主节点故障Keepalived 健康检查VIP 切换至备节点3-5 秒
PostgreSQL Leader 故障Patroni 健康监控自动选举新 Leader20-30 秒
Patroni 进程假死Watchdog 心跳检测强制重启服务/系统30-60 秒
ETCD 节点故障Raft 协议自动选举新 ETCD Leader1-2 秒
网络分区多数票原则隔离少数派节点选举超时

九、监控告警

1. 监控指标

  • HAProxy 层:连接数、队列长度、响应时间、后端节点状态
  • Keepalived 层:VIP 状态、VRRP 状态、节点优先级
  • Patroni 层:节点角色、复制延迟、选举状态
  • PostgreSQL 层:连接数、TPS、锁等待、WAL 位置
  • ETCD 层:集群健康、Leader 状态、提案延迟
  • Watchdog 层:心跳状态、重启次数

2. 告警规则

  • VIP 切换告警
  • PostgreSQL 主备切换告警
  • 复制延迟超阈值告警
  • ETCD 集群成员变更告警
  • Watchdog 触发重启告警

十、参考资料

  1. Patroni + HAProxy + Keepalived + ETCD 搭建高可用 PostgreSQL 集群
最后修改:2026 年 01 月 15 日
如果觉得我的文章对你有用,请随意赞赏