生产环境PostgreSQL逻辑复制与高可用架构实战经验分享

生产环境PostgreSQL逻辑复制与高可用架构实战经验分享_第1张图片

生产环境PostgreSQL逻辑复制与高可用架构实战经验分享

在大规模业务场景中,数据可靠性与可用性至关重要。本文结合真实生产环境案例,分享基于PostgreSQL逻辑复制(Logical Replication)与流复制(Streaming Replication)建设高可用架构的全流程,包括选型、部署、故障切换与优化思考,为有一定数据库运维和后端基础的读者提供可落地的实战经验。

一、业务场景描述

  1. 业务特点:

    • 日活用户峰值达 50W+,每日交易写入量稳定在数百万级别
    • 对数据一致性要求较高,容忍度在 1 ~ 5s 以内
    • ROI 要求短响应时间,查询性能需要支撑复杂 OLAP 分析以及部分 BI 报表需求
  2. 可用性需求:

    • RPO ≤ 5s,RTO ≤ 30s
    • 主节点故障时快速完成故障切换,切换脚本与监控报警系统联动
  3. 技术现状:

    • 现有 PostgreSQL 12 单主多从架构,通过流复制进行同步,但在长期运维中出现主库切换时数据丢失、流复制延迟和拆表不一致等问题
    • 需要将逻辑复制引入,实现基于发布/订阅模型的表级订阅,满足对部分业务表灵活订阅与对等扩展需求

二、技术选型过程

  1. 流复制 vs 逻辑复制

    • 流复制(Streaming Replication)只能做整实例的复制,适合 Disaster Recovery,延迟低,但无法针对单表或排除表进行复制;
    • 逻辑复制(Logical Replication)支持基于发布/订阅模型,按表粒度订阅,可在不同版本或拓扑间迁移;
  2. 组件选择

    • 发布端:内置 PostgreSQL 12 版本的 logical replication 功能;
    • 订阅端:同版本 PostgreSQL 服务,网络互通;
    • 监控与切换:使用开源 Patroni + Etcd 实现 HA 管理与 Leader 选举;
  3. 方案对比表

| 特性 | 流复制 | 逻辑复制 | Patroni+Etcd | | ------------------- | --------------- | --------------- | ------------------ | | 复制粒度 | 实例 | 表 | N/A | | 延迟 | ~10ms | ~100ms | N/A | | 断点续传 | 原生支持 | 需手工重建订阅 | N/A | | HA 管理 | 需外部脚本 | 需外部脚本 | 原生支持 Leader 选举 | | 弹性扩展 | 较弱 | 强 | N/A |

综合评估:结合生产环境需求,主备流复制保证主节点容灾,逻辑复制用于跨集群或业务拆分订阅,Patroni+Etcd 做整个集群的自动选主与故障恢复。

三、实现方案详解

3.1 环境准备

  • PostgreSQL 12.8 安装,开启 wal_level=logical
  • 配置主从网络连通,调整相关参数:

postgresql.conf:

# 开启逻辑复制
wal_level = logical              # logical 或更高
max_replication_slots = 10       # 根据业务订阅需求配置
max_wal_senders = 10             # 与 max_replication_slots 保持一致
wal_keep_segments = 512          # 保留 WAL 文件数量
synchronous_commit = on          # 保证事务提交后实时推送副本

pg_hba.conf:

# 允许复制角色连接
host    replication     repl_user       standby_ip/32      md5
host    all             all             standby_ip/32      md5

重启 PostgreSQL:

systemctl restart postgresql-12

3.2 搭建 Patroni 集群

  1. 安装依赖:Python3、pip、etcd
pip3 install patroni[etcd]
# 安装 etcd
wget https://github.com/etcd-io/etcd/releases/download/v3.4.15/etcd-v3.4.15-linux-amd64.tar.gz
  1. 配置 Patroni YAML(示例)
scope: pg_cluster
namespace: /db/
name: postgresql-1
restapi:
  listen: 0.0.0.0:8008
  connect_address: 10.0.1.11:8008
etcd:
  host: 127.0.0.1:2379
bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
  initdb:
  - encoding: UTF8
  - data-checksums
postgresql:
  listen: 0.0.0.0:5432
  connect_address: 10.0.1.11:5432
  data_dir: /data/pg12/data
  bin_dir: /usr/pgsql-12/bin
  parameters:
    wal_level: logical
    max_wal_senders: 10
    max_replication_slots: 10
    wal_keep_segments: 512
    synchronous_commit: on
  authentication:
    replication:
      username: repl_user
      password: repl_password
    superuser:
      username: postgres
      password: super_password

启动 Patroni:

patroni /etc/patroni.yml &

等待 etcd 中选举出 Leader,其他节点自动跟随。

3.3 配置逻辑复制

  1. 在主节点创建发布:
-- 创建复制角色
CREATE ROLE repl_logical WITH REPLICATION PASSWORD 'repl_logic_pw' LOGIN;
-- 定义发布
CREATE PUBLICATION pub_all FOR TABLE orders, order_items, customers;
  1. 在订阅端建立订阅:
CREATE SUBSCRIPTION sub_pub_all
CONNECTION 'host=10.0.1.11 port=5432 user=repl_logical password=repl_logic_pw dbname=mydb'
PUBLICATION pub_all;
  1. 检查同步状态:
-- 查看发布状态
SELECT * FROM pg_publication;
-- 查看订阅状态
SELECT * FROM pg_subscription;
-- 查看复制槽使用情况
SELECT * FROM pg_replication_slots;

3.4 故障切换与监控

  1. 故障检测:Patroni 内置健康检查,发现主节点宕机后自动触发 failover。
  2. 故障切换:新的 Leader 接管写请求,逻辑复制、流复制配置保持不变。
  3. 数据重平衡:自动恢复后旧主挂载为从节点并同步数据。
  4. 监控集成:使用 Prometheus + Grafana 收集以下指标:
    • replication_lag
    • rep_slots_active
    • patroni_cluster_status
# prometheus.yml snippet
- job_name: 'postgres'
  static_configs:
  - targets: ['10.0.1.11:9187','10.0.1.12:9187']

Grafana 可视化看板:

  • 主从延迟趋势图
  • 复制槽使用情况
  • Patroni 集群拓扑

四、踩过的坑与解决方案

  1. 复制槽累积引发磁盘占满: 问题:复制槽在订阅端宕机后无法自动清理,WAL 文件持续增长; 解决:定期清理无效订阅并根据业务设置合理的 wal_keep_segments。

  2. 逻辑复制延迟过高: 问题:大事务导入导致订阅端堆积; 解决:控制批量提交大小(commit delay),或拆分为小事务; 示例:

BEGIN;
INSERT INTO orders VALUES (...);
INSERT INTO order_items VALUES (...);
COMMIT;
-- 控制单批事务大小在 10k 行以内
  1. Patroni 节点漂移(split-brain): 问题:etcd 网络抖动导致多主; 解决:调整 DCS 参数 (ttl, retry_timeout) 并加固 etcd 集群网络可靠性。

  2. 主库 DDL 操作与逻辑复制冲突: 问题:逻辑复制默认不复制所有 DDL; 解决:采用 pglogical 插件补充 DDL 同步,或在维护窗口内手动执行 DDL。

五、总结与最佳实践

  1. 混合复制架构:生产环境建议主备使用流复制保证低 RPO,跨机房、跨版本使用逻辑复制灵活订阅;
  2. 自动化运维:Patroni + Etcd/Consul 提供健康检查与自动故障切换,结合 Prometheus 报警实现 DevOps 自动化;
  3. 监控与容量规划:持续关注 replication_lag、wal 生成速率与磁盘使用量,定期演练故障切换;
  4. 事务粒度控制:控制大事务写入,将业务拆分为多批小事务,降低订阅端压力;
  5. 灰度发布策略:利用逻辑复制可支持跨版本升级,先升级订阅端、验证无误后再升级发布端;

通过以上实战经验分享,读者可以在真实生产环境中快速搭建高可用、低延迟且灵活可扩展的 PostgreSQL 复制架构,为大规模业务保驾护航。

你可能感兴趣的:(后端技术栈小结,PostgreSQL,逻辑复制,高可用)