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

PostgreSQL流复制(Streaming Replication)是构建数据库高可用架构的核心机制,通过实时同步WAL(Write-Ahead Log)日志实现主从节点的数据一致性。配合Patroni集群管理工具,可以实现自动故障检测和主从切换,满足生产环境对数据库高可用和故障恢复的严苛要求。在高并发读写场景下,主从读写分离还能有效提升数据库的查询吞吐量。

PostgreSQL流复制架构原理

PostgreSQL流复制基于WAL日志的实时传输。主节点(Primary)将事务产生的WAL日志写入本地WAL缓冲区后,通过TCP连接将日志流发送给备节点(Standby)。备节点接收日志后回放(Replay)WAL记录,将变更应用到本地数据文件。整个流程是异步的,主节点不需要等待备节点确认即可提交事务。

流复制分为异步复制和同步复制两种模式。异步复制中主节点提交事务后立即返回,不等待备节点确认,延迟最低但存在数据丢失风险。同步复制通过synchronous_commit和synchronous_standby_names参数配置,要求至少一个备节点确认接收WAL日志后主节点才提交,保证数据零丢失但会增加提交延迟。

-- Check replication status
SELECT pid, state, sync_state, sent_lsn, write_lsn,
       flush_lsn, replay_lsn, write_lag, flush_lag, replay_lag
FROM pg_stat_replication;

-- Check standby receiver
SELECT status, receive_start_lsn, written_lsn, flushed_lsn
FROM pg_stat_wal_receiver;

sent_lsn、write_lsn、flush_lsn和replay_lsn之间的差距反映了复制的延迟阶段。write_lag表示日志写入备节点文件系统的延迟,flush_lag表示刷盘延迟,replay_lag表示回放延迟。生产环境中replay_lag是最关键的健康指标,持续增长意味着备节点处理能力不足。

主节点WAL日志配置

主节点的postgresql.conf需要配置WAL日志和复制相关参数。合理的WAL配置直接影响复制延迟和主节点写入性能。

# postgresql.conf - Primary
wal_level = replica
max_wal_senders = 10
max_replication_slots = 10
wal_keep_size = 2048
wal_buffers = 64MB
synchronous_commit = on
checkpoint_timeout = 15min
max_wal_size = 4GB
min_wal_size = 1GB
checkpoint_completion_target = 0.9
archive_mode = on
archive_command = 'test ! -f /archive/%f && cp %p /archive/%f'

wal_keep_size参数控制主节点保留的WAL日志量,确保备节点断连后重连时主节点仍有足够的WAL日志可供发送。该值需要根据网络稳定性和备节点恢复时间评估,设置过小会导致备节点需要全量基础备份重建。复制槽(Replication Slot)自动管理WAL日志保留,防止备节点断连时主节点过早清理WAL导致无法重连。

从节点流复制连接设置

从节点的配置需要设置连接主节点的参数和回放策略。standby.signal文件的存在标识该节点为备节点。

# postgresql.conf - Standby
hot_standby = on
hot_standby_feedback = on
max_standby_streaming_delay = 30s

# postgresql.auto.conf
primary_conninfo = 'host=primary.pg.local port=5432 user=replica password=ReplicaPass123'
primary_slot_name = 'standby1_slot'
restore_command = 'cp /archive/%f %p'
recovery_target_timeline = 'latest'

在主节点创建复制用户和复制槽:

CREATE ROLE replica WITH REPLICATION LOGIN PASSWORD 'ReplicaPass123';
SELECT pg_create_physical_replication_slot('standby1_slot');
SELECT slot_name, slot_type, active, restart_lsn FROM pg_replication_slots;

hot_standby_feedback=on让备节点向主节点发送当前最旧的活跃事务XID,主节点据此推迟清理旧版本数据,避免备节点长查询因快照过期而报错。max_standby_streaming_delay设置了备节点在回放WAL与处理查询冲突时的等待时间,超时后备节点会取消冲突的查询以继续回放。

复制槽管理与日志保留策略

复制槽解决了备节点断连后WAL日志被清理的问题,但引入了新的风险:如果备节点长期断连,主节点会无限保留WAL日志,导致pg_wal目录持续增长直至磁盘满。需要建立复制槽监控和告警机制。

-- Check slot WAL retention
SELECT slot_name, active, restart_lsn,
       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) as retained_wal
FROM pg_replication_slots;

-- Monitor pg_wal directory size
SELECT pg_size_pretty(sum(size)) as wal_dir_size
FROM pg_ls_waldir();

对于不需要保证WAL连续性的场景,可以不使用复制槽而依赖wal_keep_size参数保留固定量的WAL日志。这种方式更简单但无法动态适应备节点的恢复需求。生产环境中建议使用复制槽配合监控告警,在保留数据安全和控制磁盘使用之间取得平衡。

Patroni自动故障转移集群配置

Patroni是Zalando开源的PostgreSQL高可用管理工具,通过etcd或Consul作为分布式配置存储,实现Leader选举和自动故障转移。Patroni监控主节点健康状态,在主节点不可用时自动将一个备节点提升为新的主节点。

# patroni.yml
scope: pg-cluster
name: node1
restapi:
  listen: 0.0.0.0:8008
  connect_address: 192.168.1.10:8008
etcd:
  hosts: 192.168.1.100:2379,192.168.1.101:2379,192.168.1.102:2379
bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 20
    maximum_lag_on_failover: 1048576
    synchronous_mode: true
    postgresql:
      use_pg_rewind: true
postgresql:
  listen: 0.0.0.0:5432
  connect_address: 192.168.1.10:5432
  data_dir: /var/lib/postgresql/data
  authentication:
    replication:
      username: replica
      password: ReplicaPass123
    superuser:
      username: postgres
      password: PostgresPass123
  parameters:
    hot_standby: on
    hot_standby_feedback: on

maximum_lag_on_failover参数设置了故障转移时备节点允许的最大复制延迟(字节),超过该值的备节点不会被提升为主节点,避免数据丢失。synchronous_mode启用同步复制,确保故障转移时数据零丢失。use_pg_rewind允许原主节点在故障恢复后通过pg_rewind重放差异日志,快速重新加入集群而不需要全量基础备份。

# Start Patroni
patroni /etc/patroni/patroni.yml &

# Check cluster status
patronictl list
# | Member | Host          | Role    | State    | TL | Lag in MB |
# | node1  | 192.168.1.10  | Leader  | running  |  5 |           |
# | node2  | 192.168.1.11  | Replica | streaming|  5 |        0  |
# | node3  | 192.168.1.12  | Replica | streaming|  5 |        0  |

# Manual switchover
patronictl switchover --master node1 --candidate node2

Patroni配合HAProxy和Keepalived可以实现客户端的透明连接路由。HAProxy通过Patroni REST API的健康检查接口区分主节点和备节点,将写请求路由到主节点,读请求可负载均衡到所有节点。故障转移时Patroni更新etcd中的Leader信息,HAProxy自动检测到新的主节点并切换路由,整个切换过程通常在10到30秒内完成。对于要求零中断的场景,可以结合PgBouncer连接池实现连接保持,减少故障转移期间的连接断开影响。

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

(0)
小编小编
上一篇 1天前
下一篇 1天前

相关推荐