Ответ
Для обеспечения отказоустойчивости и балансировки нагрузки читающих запросов мы настроили асинхронную потоковую репликацию PostgreSQL в режиме hot standby, управляемую Patroni для автоматического фейловера.
Архитектура:
- 1 Primary (Master): Принимает все операции записи.
- 2 Replica (Hot Standby): Принимают поток WAL (Write-Ahead Log) с мастера, применяют его и готовы в любой момент стать новым мастером. Одна реплика использовалась для чтения приложениями, вторая — для бэкапов и аналитических запросов.
Настройка PostgreSQL:
На Primary (postgresql.conf):
wal_level = replica # Достаточный уровень для репликации
max_wal_senders = 5 # Количество одновременно подключаемых реплик
wal_keep_size = 10GB # Минимальный объем WAL-файлов для хранения
hot_standby = on # Разрешаем выполнять запросы на репликах
На Replica (primary_conninfo в postgresql.auto.conf, генерируется Patroni):
primary_conninfo = 'host=postgres-primary user=replicator password=... application_name=replica1'
Оркестрация через Patroni: Patroni, используя распределенное хранилище etcd в качестве DCS (Distributed Configuration Store), управляла жизненным циклом кластера:
- Автоматически продвигал реплику в мастера при падении текущего primary.
- Переконфигурировал оставшиеся ноды на подключение к новому мастеру.
- Предоставлял единую точку доступа через DNS-запись/сервис
postgres-leader.
Мониторинг:
- Лаг репликации: Отслеживал через запрос
SELECT client_addr, state, pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replay_lag_bytes FROM pg_stat_replication;и выставлял метрику в Prometheus. - Алерты: В Alertmanager были настроены алерты на критический лаг репликации (> 100 МБ) и потерю реплики.
Пример команды для проверки статуса через Patroni:
patronictl -c /etc/patroni/patroni.yml list
# Output example:
+ Cluster: postgres-cluster (6971258148830274863) ---+
| Member | Host | Role | State | TL | Lag in MB |
|---------------+-------------+---------+---------+----+-----------|
| postgres-node1| 10.10.1.101 | Leader | running | 42 | |
| postgres-node2| 10.10.1.102 | Replica | running | 42 | 0 |
| postgres-node3| 10.10.1.103 | Replica | running | 42 | 0 |
+---------------+-------------+---------+---------+----+-----------+