Как была настроена репликация на последнем проекте?

«Как была настроена репликация на последнем проекте?» — вопрос из категории Базы данных, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для обеспечения отказоустойчивости и балансировки нагрузки читающих запросов мы настроили асинхронную потоковую репликацию 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 |
+---------------+-------------+---------+---------+----+-----------+