Ответ
Для обеспечения отказоустойчивости PostgreSQL я настраиваю репликацию и автоматическое переключение (failover), чтобы при падении мастера одна из реплик могла взять на себя его роль с минимальным временем простоя.
Типичная архитектура HA-кластера: Я предпочитаю использовать Patroni в связке с etcd (или ZooKeeper) как дистрибьютированное хранилище конфигурации (DCS). Это решение автоматизирует failover, переконфигурацию и предотвращает split-brain.
Состав кластера (минимум 3 ноды):
- PostgreSQL + Patroni на каждой ноде.
- etcd-кластер (отдельно или co-located) из 3 или 5 нод для кворума.
Как это работает:
- Patroni на каждой ноде управляет экземпляром PostgreSQL и через etcd координирует выбор лидера (мастера).
- Только мастер принимает запись. Реплики работают в режиме потоковой репликации (streaming replication).
- При падении мастера Patroni автоматически проводит выборы и promotes одну из синхронных реплик в нового мастера. Остальные реплики переключаются на него.
Конфигурация (упрощённо):
# Фрагмент конфига Patroni (patroni.yml)
scope: my-postgres-cluster
namespace: /service/
name: node1
restapi:
listen: 0.0.0.0:8008
connect_address: 10.0.1.1:8008
etcd:
hosts: 10.0.1.10:2379,10.0.1.11:2379,10.0.1.12:2379
bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
postgresql:
use_pg_rewind: true
parameters:
wal_level: replica
hot_standby: "on"
max_wal_senders: 10
wal_keep_size: 1GB
Для подключения приложений:
- Использую HAProxy или PgBouncer в режиме transaction pooling перед кластером. Они получают от Patroni статус нод (через REST API
/primaryили/read-only) и направляют write-запросы на текущего мастера, а read-запросы — на реплики. - В DNS или строке подключения приложения указываю адрес балансировщика, а не конкретную ноду БД.
Резервное копирование: Отказоустойчивость — не замена бэкапам. Параллельно настраиваю pg_basebackup и WAL-архивацию в объектное хранилище (S3) с помощью pgBackRest или WAL-G для возможности Point-in-Time Recovery (PITR).