PostgreSQL高可用架构实战:流复制主从配置与Patroni自动故障转移

PostgreSQL通过流复制(Streaming Replication)实现主从同步,配合Patroni自动故障转移工具可以构建生产级高可用集群。数据库高可用架构设计的核心目标是:主节点故障时自动选举新主节点、数据零丢失、业务无感知切换。本文从流复制基础配置到Patroni集群编排,完整搭建PostgreSQL高可用方案。

PostgreSQL流复制原理与主节点配置

流复制是PostgreSQL原生支持的物理复制方式,主节点将WAL(Write-Ahead Log)日志流实时发送到备节点,备节点重放WAL实现数据同步。与逻辑复制不同,流复制是实例级全量复制,备节点为只读状态。数据库运维中,流复制常用于读负载分离和故障转移。同步级别通过synchronous_commit参数控制,remote_apply提供最强一致性保证。

# postgresql.conf - 主节点配置
wal_level = replica
max_wal_senders = 10
wal_keep_size = 1024     # 保留1GB WAL用于备节点追赶
synchronous_standby_names = 'FIRST 2 (pg-slave1, pg-slave2)'
synchronous_commit = remote_apply   # 同步级别:remote_apply最高
archive_mode = on
archive_command = 'test ! -f /data/wal_archive/%f && cp %p /data/wal_archive/%f'
hot_standby = on
listen_addresses = '*'
port = 5432

# pg_hba.conf - 允许备节点连接
host replication replicator 10.0.1.0/24 md5
host all all 10.0.1.0/24 md5

# 创建复制用户
psql -c "CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'repl_pass';"

备节点搭建与基线备份初始化

备节点的搭建需要从主节点创建基线备份,然后配置recovery参数启动流复制。数据备份恢复中,pg_basebackup工具是创建物理备份的标准方法,它会在备节点创建standby.signal文件并配置primary_conninfo连接信息。

# 方法一:pg_basebackup(推荐)
pg_basebackup -h 10.0.1.10 -U replicator -D /data/pgdata -Fp -Xs -P -R

# -Fp: 平面文件格式
# -Xs: 流式传输WAL
# -P: 显示进度
# -R: 自动生成standby.signal和primary_conninfo配置

# 生成的postgresql.auto.conf内容
# primary_conninfo = 'host=10.0.1.10 port=5432 user=replicator password=repl_pass application_name=pg-slave1'
# primary_slot_name = 'slave1_slot'

# 方法二:手动创建基础备份
# 在主节点执行
psql -c "SELECT pg_start_backup('base_backup', true);"
# 复制数据目录到备节点
rsync -av /data/pgdata/ pg-slave1:/data/pgdata/
# 在主节点执行
psql -c "SELECT pg_stop_backup();"

# 备节点配置
# /data/pgdata/postgresql.auto.conf
primary_conninfo = 'host=10.0.1.10 port=5432 user=replicator password=repl_pass application_name=pg-slave1'
restore_command = 'cp /data/wal_archive/%f %p'
recovery_target_timeline = 'latest'

# 创建复制槽(防止WAL被过早清理)
psql -c "SELECT pg_create_physical_replication_slot('slave1_slot');"

# 启动备节点
pg_ctl -D /data/pgdata start

# 验证复制状态(主节点执行)
psql -c "SELECT * FROM pg_stat_replication;"
psql -c "SELECT application_name, state, sync_state, sent_lsn, write_lsn, flush_lsn, replay_lsn FROM pg_stat_replication;"

Patroni集群管理与自动故障转移配置

Patroni是PostgreSQL高可用管理工具,基于分布式配置存储(etcd/ZooKeeper/Consul)实现集群协调。当主节点故障时,Patroni自动选举最优备节点提升为新主,并更新连接路由。数据迁移实战中,Patroni支持手动switchover(计划内切换)和自动failover(故障切换)两种模式。

# patroni.yml - 节点1配置
scope: pg-cluster
name: pg-node1

restapi:
  listen: 0.0.0.0:8008
  connect_address: 10.0.1.10:8008

etcd:
  hosts: 10.0.1.20:2379,10.0.1.21:2379,10.0.1.22:2379

bootstrap:
  initdb:
    - encoding: UTF8
    - locale: C.UTF-8
    - data-checksums
  post_bootstrap: /opt/pg_scripts/post_bootstrap.sh
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 20
    maximum_lag_on_failover: 1048576
    synchronous_mode: true
    synchronous_mode_strict: false
    postgresql:
      use_pg_rewind: true
      parameters:
        wal_level: replica
        max_wal_senders: 10
        synchronous_commit: remote_apply

postgresql:
  listen: 0.0.0.0:5432
  connect_address: 10.0.1.10:5432
  data_dir: /data/pgdata
  bin_dir: /usr/lib/postgresql/16/bin
  config_dir: /data/pgdata
  pg_hba:
    - host replication replicator 10.0.1.0/24 md5
    - host all all 10.0.1.0/24 md5
  authentication:
    replication:
      username: replicator
      password: repl_pass
    superuser:
      username: postgres
      password: pg_pass
  parameters:
    max_connections: 200
    shared_buffers: 4GB
    effective_cache_size: 12GB
    work_mem: 64MB
    maintenance_work_mem: 1GB
    checkpoint_completion_target: 0.9
    wal_buffers: 16MB
    default_statistics_target: 100
    random_page_cost: 1.1
    effective_io_concurrency: 200

tags:
  nofailover: false
  noloadbalance: false
  clonefrom: false
  nosync: false

HAProxy连接路由与读写分离配置

Patroni配合HAProxy实现读写分离:写请求路由到主节点,读请求分发到备节点。HAProxy通过Patroni的REST API健康检查端点判断节点角色,动态调整后端路由。数据库高可用架构中,连接层的高可用是应用无感知切换的关键。

# haproxy.cfg
global
    maxconn 2000
    log /dev/log local0

defaults
    log global
    mode tcp
    option tcplog
    timeout connect 5s
    timeout client 30s
    timeout server 30s

# 主节点连接(写请求)
frontend pg_write
    bind *:5432
    default_backend pg_master

backend pg_master
    option httpchk
    httpchk GET /primary
    server pg-node1 10.0.1.10:5432 check port 8008 inter 2s fall 2 rise 2
    server pg-node2 10.0.1.11:5432 check port 8008 inter 2s fall 2 rise 2
    server pg-node3 10.0.1.12:5432 check port 8008 inter 2s fall 2 rise 2

# 备节点连接(读请求)
frontend pg_read
    bind *:5433
    default_backend pg_replicas

backend pg_replicas
    option httpchk
    httpchk GET /replica
    balance roundrobin
    server pg-node1 10.0.1.10:5432 check port 8008 inter 2s fall 2 rise 2
    server pg-node2 10.0.1.11:5432 check port 8008 inter 2s fall 2 rise 2
    server pg-node3 10.0.1.12:5432 check port 8008 inter 2s fall 2 rise 2

故障转移测试与数据一致性验证

高可用方案上线前必须进行故障转移测试,验证切换时间和数据一致性。Patroni提供了switchover和failover两种切换方式。SQL查询优化场景中,备节点上的长查询可能影响切换速度,需要合理设置max_standby_streaming_delay参数。

# 手动switchover(计划内切换)
patronictl switchover --master pg-node1 --candidate pg-node2 --force pg-cluster

# 模拟主节点故障
# 在主节点停止PostgreSQL
pg_ctl -D /data/pgdata stop -m fast

# 观察Patroni自动failover
patronictl list pg-cluster
# +---------+--------+---------+----+-----------+
# | Member  | Role   | State   | TL | Lag in MB |
# +---------+--------+---------+----+-----------+
# | pg-node1| Unkn   | Stopped |    |   unknown |
# | pg-node2| Leader | Running | 12  |          0|
# | pg-node3| Replica| Streaming| 12 |          0|
# +---------+--------+---------+----+-----------+

# 验证数据一致性
# 在新主节点执行
psql -c "SELECT pg_current_wal_lsn();"
# 在备节点执行
psql -c "SELECT pg_last_wal_replay_lsn();"

# 检查复制延迟
psql -c "
SELECT application_name, 
       pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes,
       state, sync_state
FROM pg_stat_replication;"

# 配置参数减少备节点查询对切换的影响
max_standby_streaming_delay = 30s
max_standby_archive_delay = 30s
hot_standby_feedback = on

PostgreSQL高可用架构的核心价值在于数据零丢失和业务连续性。流复制保证数据实时同步,Patroni实现自动故障转移,HAProxy完成连接路由。数据库运维中,定期演练故障转移流程是保障系统韧性的必要手段。配合pgBackRest或WAL-G进行物理备份,可以在极端故障场景下实现时间点恢复,进一步提升数据安全级别。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/postgresql-gao-ke-yong-jia-gou-shi-zhan-liu-fu-zhi-zhu-cong/

(0)
小编小编
上一篇 20小时前
下一篇 20小时前

相关推荐