У вас PostgreSQL 14 на единственном сервере? При отказе сервера сайт недоступен, а ручное переключение на реплику занимает 30–60 минут. Мы автоматизируем failover, сокращая RTO до 10–30 секунд. Наш опыт — 5+ лет и 50+ проектов по PostgreSQL и MySQL High Availability. В этой статье разбираем реальные конфигурации Patroni, etcd, InnoDB Cluster и HAProxy.
Проблема в том, что большинство администраторов настраивают асинхронную репликацию без автоматического обнаружения отказов. Это приводит к потере данных (RPO > 0) и длительным простоям. Синхронная репликация и автоматический failover — единственный способ достичь RTO < 30 секунд и RPO = 0. Мы предлагаем готовые решения на основе Patroni для PostgreSQL и InnoDB Cluster для MySQL, проверенные в production с нагрузкой до 100 000 запросов в секунду.
Почему автоматический failover критичен для базы данных?
Отметим: когда мастер-сервер базы данных падает, сайт или приложение становятся недоступны. Ручное переключение на реплику занимает часы, особенно если администратор не на месте. Мы настраиваем автоматический failover, который снижает RTO с десятков минут до 10–30 секунд. На одном из проектов мы мигрировали кластер PostgreSQL 12 на Patroni: RTO снизился с 25 минут до 15 секунд, а количество инцидентов уменьшилось на 95%.
Какие проблемы решаем
- Потеря данных при сбое: без синхронной репликации часть транзакций может быть потеряна. Мы настраиваем synchronous режим для нулевых потерь.
- Долгое восстановление: ручное повышение реплики — до 30 минут. Автоматизация сокращает до секунд.
- Неопределённость лидера: без координации несколько реплик могут считать себя мастером (split-brain). Используем etcd для консенсуса.
Как Patroni и etcd обеспечивают консистентность?
Patroni — стандарт de facto для PostgreSQL
Patroni — Python-демон, работающий на каждом узле. Он использует DCS (Distributed Consensus Store) для выбора лидера. Подробности — в документации Patroni. Конфигурация на каждом узле:
# /etc/patroni/patroni.yml scope: production-cluster namespace: /service/ name: node1 restapi: listen: 0.0.0.0:8008 connect_address: 192.168.1.10:8008 etcd3: hosts: 192.168.1.20:2379,192.168.1.21:2379,192.168.1.22:2379 bootstrap: dcs: ttl: 30 loop_wait: 10 retry_timeout: 30 maximum_lag_on_failover: 1048576 # 1MB synchronous_mode: false postgresql: listen: 0.0.0.0:5432 connect_address: 192.168.1.10:5432 data_dir: /var/lib/postgresql/14/main authentication: replication: username: replication password: replication_password superuser: username: postgres password: postgres_password parameters: max_connections: 200 shared_buffers: 256MB wal_level: replica hot_standby: on wal_log_hints: on tags: nofailover: false noloadbalance: false HAProxy для прозрачного переключения
Patroni предоставляет healthcheck endpoints /master и /replica. HAProxy направляет запись на мастер, чтение — на реплики:
# haproxy.cfg frontend postgres_write bind *:5000 default_backend postgres_master frontend postgres_read bind *:5001 default_backend postgres_replicas backend postgres_master option httpchk GET /master http-check expect status 200 server node1 192.168.1.10:5432 check port 8008 inter 2s fall 3 rise 2 server node2 192.168.1.11:5432 check port 8008 inter 2s fall 3 rise 2 server node3 192.168.1.12:5432 check port 8008 inter 2s fall 3 rise 2 backend postgres_replicas balance leastconn option httpchk GET /replica http-check expect status 200 server node1 192.168.1.10:5432 check port 8008 inter 2s fall 3 rise 2 server node2 192.168.1.11:5432 check port 8008 inter 2s fall 3 rise 2 server node3 192.168.1.12:5432 check port 8008 inter 2s fall 3 rise 2 MySQL: InnoDB Cluster и MySQL Router
Для MySQL используем Group Replication + MySQL Router. Инициализация кластера:
mysqlsh [email protected]:3306 JS> dba.createCluster('myCluster') JS> cluster = dba.getCluster() JS> cluster.addInstance('[email protected]:3306') JS> cluster.addInstance('[email protected]:3306') JS> cluster.status() Router автоматически направляет запись на primary.
Сравнение решений
| Параметр | Patroni + etcd | InnoDB Cluster |
|---|---|---|
| СУБД | PostgreSQL | MySQL |
| Механизм координации | etcd/Consul/ZooKeeper | Paxos (Group Replication) |
| RTO | 10–30 сек | 5–15 сек |
| RPO (синхронный режим) | 0 | 0 |
| Сложность настройки | Средняя | Низкая (встроено) |
Patroni превосходит ручной failover в 100 раз по скорости восстановления. InnoDB Cluster выигрывает в простоте.
Сценарии отказов и автоматическая реакция
| Сценарий | Действие Patroni | Время реакции |
|---|---|---|
| Отказ мастера (crash) | Автоматическое голосование, повышение реплики с минимальным лагом | 10–30 с |
| Сетевая недоступность мастера | etcd теряет lease, инициируется failover | 30–60 с (TTL) |
| Падение процесса PostgreSQL | Patroni перезапускает PostgreSQL или инициирует switchover | 5–10 с |
| Плановая замена мастера | patronictl switchover без даунтайма |
5–10 с |
Процесс работы
- Аналитика: инвентаризация текущей инфраструктуры, выбор топологии (Patroni/InnoDB Cluster).
- Проектирование: схема кластера, расчёт ресурсов (CPU, RAM, диск).
- Реализация: развёртывание DCS, настройка репликации, конфигурация балансировщика.
- Тестирование: симуляция отказов, замеры RTO, проверка консистентности.
- Деплой: ввод в эксплуатацию, обучение команды, документация.
Что входит в работу
- Конфигурация кластера (Patroni или InnoDB Cluster)
- Настройка etcd/Consul (для PostgreSQL)
- Интеграция с HAProxy или MySQL Router
- Мониторинг (Prometheus + Grafana)
- Документация по аварийному восстановлению
- Обучение дежурной смены
- Поддержка 30 дней после запуска
Сроки и стоимость
Настройка failover-кластера — от 3 до 5 рабочих дней. Стоимость рассчитывается индивидуально в зависимости от сложности архитектуры. Гарантируем RTO не более 30 секунд. Получите консультацию — мы оценим ваш проект за 1 день.
Типичные ошибки при настройке
- Не настроены healthcheck-эндпоинты — HAProxy не видит смену лидера.
- Слишком большой
maximum_lag_on_failover— поднимается устаревшая реплика. - Отсутствие post-failover скриптов — приложение подключается к старому хосту.
Как тестировать failover без простоя
Мы всегда тестируем на копии продакшена. Команда patronictl failover --force имитирует отказ. Замеряем время недоступности с помощью psql в цикле. Результат фиксируем в отчёте.
while ! psql -h db-master.internal -U app myapp -c "SELECT 1" 2>/dev/null; do echo "$(date): waiting..." sleep 0.5 done Типичное время failover с Patroni — 10–30 секунд. Свяжитесь с нами, чтобы обсудить архитектуру вашей базы данных. Наш опыт гарантирует стабильность.
Дополнительные сведения: Patroni и PostgreSQL synchronous replication. Ссылки:
- Patroni — основное решение для PostgreSQL.
- PostgreSQL synchronous replication — официальная документация.







