PostgreSQL高可用架构与流复制Stream Replication配置实战

PostgreSQL流复制(Streaming Replication)是构建数据库高可用架构的核心机制。主节点(Primary)通过WAL日志流实时同步到备节点(Standby),备节点持续接收并回放WAL日志保持数据一致。配合Patroni或repmgr等集群管理工具,可以实现自动故障切换,满足生产环境对数据库RPO=0和RTO在秒级的要求。本文覆盖流复制配置、故障切换和读写分离实战。

PostgreSQL流复制架构与WAL日志机制

PostgreSQL通过预写式日志(WAL)记录所有数据变更。流复制模式下,Primary持续发送WAL日志给Standby,Standby接收后写入WAL文件并回放。同步级别通过synchronous_commit参数控制:local(仅本地确认)、on(等备节点接收确认)、remote_write(等备节点写入确认)、remote_apply(等备节点回放完成)。

主节点Primary配置

# postgresql.conf(主节点)
listen_addresses = '*'
port = 5432
wal_level = replica            # 流复制需要replica级别
max_wal_senders = 10          # 最大WAL发送进程数
wal_keep_size = 1024           # 保留WAL大小(MB),防止备节点断连后追赶不上
hot_standby = on
synchronous_standby_names = '*'  # 同步复制,所有备节点参与确认

# 归档配置
archive_mode = on
archive_command = 'test ! -f /archive/%f && cp %p /archive/%f'

# 连接配置
max_connections = 200
shared_buffers = 4GB
effective_cache_size = 12GB
work_mem = 64MB
# pg_hba.conf(主节点)- 允许备节点复制连接
# TYPE  DATABASE     USER     ADDRESS          METHOD
host    replication  repl     192.168.1.0/24   md5
host    all          all      192.168.1.0/24   md5
# 创建复制专用用户
psql -U postgres -c "CREATE ROLE repl WITH REPLICATION LOGIN PASSWORD 'repl_password';"

备节点Standby配置与基础备份

使用pg_basebackup创建基础备份

# 在备节点上执行,从主节点拉取基础备份
pg_basebackup \
    -h 192.168.1.10 \
    -U repl \
    -D /var/lib/postgresql/data \
    -Fp \
    -Xs \
    -P \
    -R \
    -S standby_slot

# -Fp: plain格式,直接拷贝文件
# -Xs: 使用stream方式同步WAL
# -P: 显示进度
# -R: 自动创建standby.signal和primary_conninfo配置
# -S: 使用复制槽(推荐,防止主节点过早回收WAL)
# postgresql.conf(备节点)- 在基础备份上追加配置
hot_standby = on
hot_standby_feedback = on     # 向主节点发送反馈,防止查询冲突
max_wal_senders = 10

# postgresql.auto.conf(pg_basebackup -R自动生成)
primary_conninfo = 'host=192.168.1.10 port=5432 user=repl password=repl_password'
primary_slot_name = 'standby_slot'

使用复制槽防止WAL过早回收

# 在主节点创建物理复制槽
psql -U postgres -c "SELECT pg_create_physical_replication_slot('standby_slot');"

# 查看复制槽状态
psql -U postgres -c "SELECT slot_name, active, restart_lsn FROM pg_replication_slots;"

# 查看复制状态
psql -U postgres -c "SELECT application_name, state, sync_state, sent_lsn, write_lsn, flush_lsn, replay_lsn FROM pg_stat_replication;"

同步级别选择与性能权衡

# 异步复制(最高性能,可能丢失少量数据)
synchronous_commit = local
synchronous_standby_names = ''

# 同步复制(数据零丢失,写入延迟增加)
synchronous_commit = on
synchronous_standby_names = 'standby1'

# remote_write(平衡方案,备节点写入WAL即确认)
synchronous_commit = remote_write
synchronous_standby_names = 'standby1'

# remote_apply(备节点回放完成才确认,读一致性最好但延迟最大)
synchronous_commit = remote_apply
synchronous_standby_names = 'standby1'

Patroni自动故障切换集群部署

Patroni是PostgreSQL高可用集群管理工具,基于分布式一致性(etcd/ZooKeeper/Consul)实现Leader选举和自动切换。

# 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.20:2379,192.168.1.21:2379,192.168.1.22:2379

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 20
    maximum_lag_on_failover: 1048576  # 1MB,超过此延迟不切换
    synchronous: true
    postgresql:
      use_pg_rewind: true
      parameters:
        wal_level: replica
        max_wal_senders: 10
        wal_keep_size: 1024

  initdb:
    - encoding: UTF8
    - locale: en_US.UTF-8

postgresql:
  listen: 0.0.0.0:5432
  connect_address: 192.168.1.10:5432
  data_dir: /var/lib/postgresql/data
  bin_dir: /usr/lib/postgresql/16/bin

  authentication:
    replication:
      username: repl
      password: repl_password
    superuser:
      username: postgres
      password: pg_password

  parameters:
    hot_standby: on
    hot_standby_feedback: on

  create_replica_methods:
    - basebackup

  basebackup:
    checkpoint: fast

tags:
  nofailover: false
  noloadbalance: false
  clonefrom: false
  replicatefrom: false
# 启动Patroni(三个节点分别启动)
patroni /etc/patroni/patroni.yml

# 查看集群状态
patronictl -c /etc/patroni/patroni.yml list

# 输出示例:
# + Cluster: pg-cluster (70000000) -+---------+----+-----------+
# | Member | Host          | Role    | State   | TL | Lag in MB |
# +-------+---------------+---------+---------+----+-----------+
# | node1 | 192.168.1.10  | Leader  | running | 16 |           |
# | node2 | 192.168.1.11  | Replica | streaming | 16 | 0        |
# | node3 | 192.168.1.12  | Replica | streaming | 16 | 0        |
# +-------+---------------+---------+---------+----+-----------+

读写分离配置与连接池方案

Pgpool-II或HAProxy配合应用层路由实现读写分离,写请求到Primary,读请求到Standby:

# Pgpool-II配置 - pgpool.conf
listen_addresses = '*'
port = 9999

# 后端节点配置
backend_hostname0 = '192.168.1.10'
backend_port0 = 5432
backend_weight0 = 0          # 读不路由到主节点
backend_data_directory0 = '/var/lib/postgresql/data'

backend_hostname1 = '192.168.1.11'
backend_port1 = 5432
backend_weight1 = 1          # 读路由到备节点
backend_data_directory1 = '/var/lib/postgresql/data'

backend_hostname2 = '192.168.1.12'
backend_port2 = 5432
backend_weight2 = 1

# 读写分离模式
load_balance_mode = on
master_slave_mode = on
master_slave_sub_mode = 'stream'

# 故障检测
health_check_period = 10
health_check_timeout = 5
health_check_user = 'postgres'

故障切换测试与验证

# 手动切换(维护场景)
patronictl -c /etc/patroni/patroni.yml switchover

# 模拟主节点故障
docker stop patroni-node1

# Patroni自动选举新Leader,观察状态变化
patronictl -c /etc/patroni/patroni.yml list

# 验证复制状态
psql -h 192.168.1.11 -U postgres -c "SELECT pg_is_in_recovery();"
# 返回f表示该节点已是Primary

流复制延迟监控通过pg_stat_replication视图查看sent_lsn与replay_lsn的差距。配置告警规则:当lag超过maximum_lag_on_failover阈值时触发告警,运维人员介入排查网络或备节点性能问题。

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

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

相关推荐