强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

PostgreSQL 完全指南 / 16 - 高可用架构

第 16 章 · 高可用架构

高可用(High Availability)确保数据库服务的持续可用性。本章介绍 Patroni、pgpool-II、PgBouncer 和读写分离。


16.1 高可用方案对比

方案故障切换自动切换复杂度适用规模
Patroni秒级任意
pgpool-II秒级中型
repmgr分钟级中小型
Stolon秒级K8s
CloudNativePG秒级K8s

16.2 Patroni

Patroni 是最流行的 PostgreSQL HA 解决方案。

架构

┌─────────┐    ┌─────────┐    ┌─────────┐
│  PG 主   │    │  PG 从1  │    │  PG 从2  │
│ Patroni  │    │ Patroni  │    │ Patroni  │
└────┬─────┘    └────┬─────┘    └────┬─────┘
     │               │               │
     └───────────────┼───────────────┘
                     │
              ┌──────┴──────┐
              │  DCS (etcd/ │
              │  Consul/    │
              │  ZooKeeper) │
              └─────────────┘

Docker Compose 部署

version: "3.8"

services:
  etcd:
    image: bitnami/etcd:3.5
    environment:
      ALLOW_NONE_AUTHENTICATION: "yes"
      ETCD_ADVERTISE_CLIENT_URLS: "http://etcd:2379"
    ports:
      - "2379:2379"

  pg-master:
    image: postgres:17
    environment:
      POSTGRES_PASSWORD: password
    volumes:
      - pg_master:/var/lib/postgresql/data

  pg-replica:
    image: postgres:17
    environment:
      POSTGRES_PASSWORD: password
    volumes:
      - pg_replica:/var/lib/postgresql/data

volumes:
  pg_master:
  pg_replica:

Patroni 配置示例

# patroni.yml
scope: pg-cluster
name: pg-node-1

restapi:
  listen: 0.0.0.0:8008
  connect_address: 10.0.0.1:8008

etcd3:
  hosts: etcd1:2379,etcd2:2379,etcd3:2379

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    postgresql:
      use_pg_rewind: true
      use_slots: true
      parameters:
        wal_level: replica
        hot_standby: on
        max_wal_senders: 5
        max_replication_slots: 5
        wal_log_hints: on

postgresql:
  listen: 0.0.0.0:5432
  connect_address: 10.0.0.1:5432
  data_dir: /var/lib/postgresql/data
  authentication:
    superuser:
      username: postgres
      password: password
    replication:
      username: replicator
      password: rep_password

16.3 PgBouncer(连接池)

PgBouncer 是最流行的 PostgreSQL 连接池。

安装与配置

# 安装
sudo apt install pgbouncer

# Docker
docker run -d --name pgbouncer \
  -p 6432:5432 \
  -e DATABASE_URL="postgres://user:pass@pg-host:5432/mydb" \
  edoburu/pgbouncer
# pgbouncer.ini
[databases]
mydb = host=127.0.0.1 port=5432 dbname=mydb

[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = scram-sha-256
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 50
min_pool_size = 10
reserve_pool_size = 5
reserve_pool_timeout = 3
server_lifetime = 3600
server_idle_timeout = 600
log_connections = 1
log_disconnections = 1

连接池模式

模式说明适用场景
session连接绑定会话需要会话级对象(临时表、PREPARE)
transaction连接在事务级别复用推荐大多数场景
statement每条语句后释放连接最高复用率,不支持多语句事务

⚠️ 注意事项transaction 模式下不能使用 LISTEN/NOTIFY、临时表、PREPARE 语句等会话级功能。


16.4 pgpool-II

pgpool-II 提供连接池、负载均衡、故障切换、查询缓存等功能。

docker run -d --name pgpool \
  -p 9999:9999 \
  -e PGPOOL_BACKEND_NODES="0:pg-master:5432,1:pg-replica:5432" \
  -e PGPOOL_SR_CHECK_USER=replicator \
  -e PGPOOL_SR_CHECK_PASSWORD=password \
  -e PGPOOL_ENABLE_LOAD_BALANCING=on \
  bitnami/pgpool:4

16.5 读写分离

-- 应用层读写分离(推荐)
-- 写操作 → 主库(端口 5432)
-- 读操作 → 从库(端口 5433)

-- PgBouncer 配置多个数据库
-- pgbouncer.ini
[databases]
mydb_rw = host=primary port=5432 dbname=mydb
mydb_ro = host=replica port=5432 dbname=mydb
# Python 示例
import psycopg2

# 写连接(主库)
write_conn = psycopg2.connect("host=primary port=6432 dbname=mydb_rw")
# 读连接(从库)
read_conn = psycopg2.connect("host=replica port=6432 dbname=mydb_ro")

业务场景

场景推荐方案
中小规模 HAPatroni + etcd
K8s 环境CloudNativePG Operator
连接池PgBouncer(transaction 模式)
读写分离PgBouncer + 多数据库路由
多活/跨地域Patroni + 同步复制

扩展阅读