PostgreSQL 18.4 高可用 Docker 部署:3 节点流复制集群搭建实战
PostgreSQL 18.4 高可用 Docker 部署:3 节点流复制集群搭建实战
在当今微服务架构盛行的时代,数据库高可用性已成为保障业务连续性的关键要素。PostgreSQL 作为最先进的开源关系型数据库,其流复制技术结合 Docker 容器化部署,能够为关键业务系统提供稳定可靠的数据服务。本文将深入探讨如何利用 Docker Compose 构建 1 主 2 从的 PostgreSQL 流复制集群,涵盖从环境准备到故障转移演练的全流程。
1. 环境准备与架构设计
1.1 基础组件选型
构建高可用 PostgreSQL 集群需要以下核心组件:
- PostgreSQL 18.4 :选择当前稳定版本,具备 WAL 日志传输和热备能力
- Docker 20.10+ :建议使用最新稳定版以获得最佳容器支持
- Docker Compose 2.20+ :用于定义和管理多容器应用
- pg_auto_failover :轻量级自动故障转移管理工具(或 Patroni)
1.2 网络拓扑设计
采用三节点部署架构确保法定人数(quorum)机制:
+-----------------+
| Application |
+--------+--------+
|
+----------------+-----------------+
| | |
+-----+------+ +-----+------+ +------+-----+
| Primary | | Standby | | Standby |
| (Node1) | | (Node2) | | (Node3) |
+------------+ +------------+ +------------+
关键配置参数对比:
| 参数 | Primary 节点 | Standby 节点 |
|---|---|---|
| hot_standby | off | on |
| wal_level | replica | replica |
| synchronous_commit | remote_apply | off |
2. Docker Compose 配置详解
2.1 完整 docker-compose.yml 配置
version: '3.8'
services:
pg-primary:
image: postgres:18.4
container_name: pg-primary
environment:
POSTGRES_PASSWORD: Str0ngP@ss
POSTGRES_USER: replicator
POSTGRES_DB: app_db
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- pgdata1:/var/lib/postgresql/data
networks:
- pg-network
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U replicator"]
interval: 5s
timeout: 5s
retries: 5
pg-standby1:
image: postgres:18.4
container_name: pg-standby1
environment:
POSTGRES_PASSWORD: Str0ngP@ss
POSTGRES_USER: replicator
POSTGRES_DB: app_db
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- pgdata2:/var/lib/postgresql/data
networks:
- pg-network
depends_on:
pg-primary:
condition: service_healthy
command: >
bash -c '
until pg_isready -h pg-primary -U replicator; do sleep 2; done;
rm -rf /var/lib/postgresql/data/pgdata/*;
pg_basebackup -h pg-primary -U replicator -D /var/lib/postgresql/data/pgdata -P -R -X stream -C -S standby1;
echo "hot_standby = on" >> /var/lib/postgresql/data/pgdata/postgresql.auto.conf;
exec docker-entrypoint.sh postgres
'
pg-standby2:
image: postgres:18.4
container_name: pg-standby2
environment:
POSTGRES_PASSWORD: Str0ngP@ss
POSTGRES_USER: replicator
POSTGRES_DB: app_db
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- pgdata3:/var/lib/postgresql/data
networks:
- pg-network
depends_on:
pg-primary:
condition: service_healthy
command: >
bash -c '
until pg_isready -h pg-primary -U replicator; do sleep 2; done;
rm -rf /var/lib/postgresql/data/pgdata/*;
pg_basebackup -h pg-primary -U replicator -D /var/lib/postgresql/data/pgdata -P -R -X stream -C -S standby2;
echo "hot_standby = on" >> /var/lib/postgresql/data/pgdata/postgresql.auto.conf;
exec docker-entrypoint.sh postgres
'
volumes:
pgdata1:
pgdata2:
pgdata3:
networks:
pg-network:
driver: bridge
2.2 关键配置解析
-
主节点配置要点 :
-
设置
PGDATA环境变量指定数据目录 - 通过健康检查确保服务可用性
- 暴露 5432 端口供应用连接
-
设置
-
备节点特殊处理 :
-
使用
pg_basebackup从主节点初始化数据 -
-R参数自动生成 recovery.conf -
-X stream启用流式 WAL 传输 -
-S指定复制槽名称避免 WAL 堆积
-
使用
-
网络配置 :
- 专用 bridge 网络确保节点间低延迟通信
- 容器间通过服务名直接访问
提示:生产环境中建议为每个节点配置独立的物理卷,避免单点故障
3. 流复制与自动故障转移配置
3.1 主节点参数调优
在主节点执行以下 SQL 配置流复制参数:
ALTER SYSTEM SET wal_level = 'replica';
ALTER SYSTEM SET max_wal_senders = 5;
ALTER SYSTEM SET wal_keep_size = '1GB';
ALTER SYSTEM SET synchronous_standby_names = 'standby1,standby2';
ALTER SYSTEM SET synchronous_commit = 'remote_apply';
验证配置生效:
docker exec -it pg-primary psql -U replicator -c "SELECT name, setting FROM pg_settings WHERE name LIKE '%wal%' OR name LIKE '%replica%';"
3.2 配置 pg_auto_failover
- 添加监控节点服务到 compose 文件:
pg-auto-failover:
image: postgres:18.4
container_name: pg-auto-failover
environment:
POSTGRES_PASSWORD: monitor@123
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- pgmonitor:/var/lib/postgresql/data
networks:
- pg-network
command: >
bash -c '
if [ ! -f /var/lib/postgresql/data/pgdata/postgresql.conf ]; then
pg_autoctl create monitor --pgdata /var/lib/postgresql/data/pgdata --auth trust --no-ssl;
fi;
pg_autoctl run
'
- 修改主备节点命令启用自动故障转移:
# 主节点命令改为:
command: >
bash -c '
if [ ! -f /var/lib/postgresql/data/pgdata/postgresql.conf ]; then
pg_autoctl create postgres --pgdata /var/lib/postgresql/data/pgdata \
--monitor postgres://autoctl_node@pg-auto-failover/pg_auto_failover \
--hostname pg-primary --auth trust --no-ssl;
fi;
exec docker-entrypoint.sh postgres
'
# 备节点命令改为:
command: >
bash -c '
until pg_isready -h pg-primary -U replicator; do sleep 2; done;
rm -rf /var/lib/postgresql/data/pgdata/*;
pg_autoctl create postgres --pgdata /var/lib/postgresql/data/pgdata \
--monitor postgres://autoctl_node@pg-auto-failover/pg_auto_failover \
--hostname pg-standby1 --auth trust --no-ssl;
exec docker-entrypoint.sh postgres
'
3.3 验证复制状态
在主节点执行:
SELECT client_addr, state, sync_priority, sync_state
FROM pg_stat_replication;
预期输出应显示两个备节点信息:
client_addr | state | sync_priority | sync_state
--------------+-----------+---------------+------------
172.20.0.3 | streaming | 1 | sync
172.20.0.4 | streaming | 2 | potential
4. 故障转移演练与监控
4.1 模拟主节点故障
- 强制停止主节点容器:
docker stop pg-primary
- 观察自动故障转移过程:
docker logs pg-auto-failover
- 验证新主节点选举:
docker exec -it pg-standby1 psql -U replicator -c "SELECT pg_is_in_recovery();"
4.2 故障恢复流程
- 修复原主节点后重新加入集群:
docker start pg-primary
docker exec -it pg-primary pg_autoctl rejoin --pgdata /var/lib/postgresql/data/pgdata
- 验证节点角色:
docker exec -it pg-auto-failover psql -U autoctl_node -d pg_auto_failover -c "SELECT formation_id, node_id, node_name, node_host, node_port, candidate_priority, replication_quorum, node_role, node_active FROM pgautofailover.node;"
4.3 监控指标配置
建议监控以下关键指标:
| 指标名称 | 监控方法 | 告警阈值 |
|---|---|---|
| 复制延迟 |
pg_stat_replication.replay_lag
| > 1MB |
| 主备连接状态 |
pg_is_in_recovery()
| 备节点返回 true |
| WAL 积压量 |
pg_current_wal_lsn()
差值
| > 4GB |
| 数据库连接数 |
pg_stat_activity
计数
| > 最大连接数 80% |
示例 Prometheus 配置:
scrape_configs:
- job_name: 'postgres'
static_configs:
- targets: ['pg-primary:9187', 'pg-standby1:9187', 'pg-standby2:9187']
metrics_path: '/metrics'
params:
dsn: ['postgresql://monitor:password@localhost:5432/postgres?sslmode=disable']
5. 性能优化与生产建议
5.1 关键参数调优
根据节点角色调整以下参数:
主节点优化 :
ALTER SYSTEM SET shared_buffers = '4GB';
ALTER SYSTEM SET effective_cache_size = '12GB';
ALTER SYSTEM SET maintenance_work_mem = '1GB';
ALTER SYSTEM SET checkpoint_completion_target = 0.9;
备节点优化 :
ALTER SYSTEM SET max_standby_streaming_delay = '30s';
ALTER SYSTEM SET hot_standby_feedback = on;
5.2 连接池配置
使用 PgBouncer 作为连接池:
pgbouncer:
image: edoburu/pgbouncer
environment:
DB_USER: replicator
DB_PASSWORD: Str0ngP@ss
DB_HOST: pg-primary
DB_NAME: app_db
POOL_MODE: transaction
MAX_CLIENT_CONN: 1000
DEFAULT_POOL_SIZE: 20
ports:
- "6432:6432"
networks:
- pg-network
depends_on:
- pg-primary
5.3 备份策略
配置每日基础备份 + WAL 归档:
# 在主节点 crontab 添加
0 2 * * * pg_basebackup -D /backups/base_$(date +\%Y\%m\%d) -Ft -z -Xs -P
* * * * * test ! -f /backups/archived/$(date +\%Y\%m\%d).log && pg_archivecleanup /backups/archived/ $(ls -t /backups/archived/ | head -n 1)
6. 常见问题排查
6.1 复制中断处理
症状
:备节点日志出现
FATAL: could not receive data from WAL stream
解决步骤 :
-
检查主节点 WAL 发送进程状态:
docker exec -it pg-primary psql -U replicator -c "SELECT * FROM pg_stat_replication;" -
必要时重建备节点:
docker-compose stop pg-standby1 docker volume rm pg_pgdata2 docker-compose up -d pg-standby1
6.2 脑裂场景处理
当网络分区导致多主情况时:
-
确定最新时间线:
docker exec -it pg-node1 cat /var/lib/postgresql/data/pgdata/pg_wal/*.history | tail -n 1 -
将旧主节点切换为备节点:
docker exec -it pg-primary pg_rewind --target-pgdata=/var/lib/postgresql/data/pgdata --source-server="host=pg-standby1 user=replicator password=Str0ngP@ss"
6.3 性能问题诊断
使用 pg_stat_statements 分析慢查询:
CREATE EXTENSION pg_stat_statements;
SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit /
nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 10;
更多推荐

所有评论(0)