Администрирование PostgreSQL, MySQL, MongoDB, Redis, Elasticsearch
Представьте: репликация настроена, бекап по расписанию, мониторинг показывает зелёный. А потом primary-нода PostgreSQL падает в 3 ночи, replica не переключается автоматически — replication slot завис, LSN отстал на 8 часов. Приложение деградирует, DBA получает звонок. Знакомо? Мы решаем такие проблемы каждый день. За 5 лет мы провели более 120 проектов по database-инфраструктуре — от стартапов до enterprise с петабайтами данных.
Большинство проблем с базами данных в production — не баги самой СУБД, а недонастроенная HA-конфигурация, отсутствие connection pooling под нагрузкой и игнорирование query planner hints до момента, когда запрос начинает занимать 30 секунд вместо 300ms. Ниже разберём типичные сценарии и наши решения.
Почему стоит настроить PostgreSQL HA через Patroni?
Patroni — де-факто стандарт для PostgreSQL HA в Kubernetes и bare metal. Он управляет leader election через DCS (etcd, Consul или ZooKeeper). Один лидер принимает запись, остальные — hot standby со streaming replication. Если лидер не отвечает на healthcheck дольше ttl секунд — Patroni инициирует выборы и промоутит лучшую реплику.
Типичная конфигурация трёхнодового кластера:
scope: postgres-ha name: pg-node-1 restapi: listen: 0.0.0.0:8008 connect_address: 10.0.1.1:8008 etcd3: hosts: 10.0.0.10:2379,10.0.0.11:2379,10.0.0.12:2379 bootstrap: dcs: ttl: 30 loop_wait: 10 retry_timeout: 10 maximum_lag_on_failover: 1048576 # 1MB — реплика с отставанием > 1MB не станет лидером postgresql: use_pg_rewind: true parameters: max_connections: 200 shared_buffers: 4GB wal_level: replica hot_standby: "on" wal_keep_size: 2GB synchronous_commit: "on" postgresql: listen: 0.0.0.0:5432 connect_address: 10.0.1.1:5432 data_dir: /data/postgresql/14/main pg_hba: - host replication replicator 10.0.0.0/24 md5 - host all all 0.0.0.0/0 md5 Параметр maximum_lag_on_failover: 1048576 — один мегабайт WAL-отставания. Реплика, отставшая больше, не промоутится, чтобы не потерять транзакции. Для нулевых потерь нужен synchronous_standby_names. Подробнее — в официальной документации Patroni.
Ещё одна проблема, которую все игнорируют: replication slots. Если приложение подключено к реплике через logical replication slot и реплика лагает — slot на primary держит WAL-файлы, и диск заполняется до отказа. PostgreSQL не удаляет WAL пока slot не освобождён. Решение: мониторить pg_replication_slots и выставить max_slot_wal_keep_size в PostgreSQL 13+:
SELECT slot_name, active, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS lag FROM pg_replication_slots ORDER BY lag DESC; SELECT pg_drop_replication_slot('slot_name'); -- осторожно — потеря данных для подписчика Как избежать connection exhaustion с PgBouncer
PostgreSQL создаёт отдельный процесс на каждое подключение. При 500 одновременных соединениях с shared_buffers=4GB тратится ~500MB только на proc structures. Приложения на Node.js или Go с connection pool по 20 подключений на инстанс при 30 инстансах дают 600 подключений — и max_connections=200 возвращает FATAL: sorry, too many clients already.
PgBouncer в режиме transaction pooling держит N подключений к PostgreSQL и мультиплексирует тысячи клиентских сессий:
[databases] mydb = host=10.0.1.1 port=5432 dbname=mydb [pgbouncer] pool_mode = transaction max_client_conn = 2000 default_pool_size = 50 reserve_pool_size = 10 reserve_pool_timeout = 5 server_idle_timeout = 600 log_connections = 0 log_disconnections = 0 Ограничение transaction pooling: нельзя использовать SET LOCAL, LISTEN/NOTIFY, advisory locks и prepared statements без server_reset_query. Это нужно учитывать при миграции.
Redis Cluster: шардирование и gotchas
Redis Cluster делит keyspace на 16384 хэш-слота, распределённых по мастер-нодам. Минимальная конфигурация — 3 мастера + 3 реплики. Каждый ключ маппится через CRC16(key) mod 16384.
Самая частая ошибка — CROSSSLOT на мультиключевых операциях. MGET key1 key2 key3 упадёт, если ключи попадают на разные слоты. Решение — hash tags: {user:123}:session и {user:123}:cart гарантированно на один слот, потому что Cluster смотрит только на часть в {}.
# Создание кластера redis-cli --cluster create \ 10.0.1.1:6379 10.0.1.2:6379 10.0.1.3:6379 \ 10.0.1.4:6379 10.0.1.5:6379 10.0.1.6:6379 \ --cluster-replicas 1 Redis Cluster не поддерживает database 0-15 (только db 0), Lua scripts с ключами на разных слотах и SCAN по всему кластеру без перебора нод. Если нужны эти возможности — рассмотрите KeyDB или Valkey как drop-in replacement с multi-threading. Для кеша персистентность часто отключают (save "", appendonly no); для session storage — AOF с appendfsync everysec (потеря 1 секунды данных приемлема), для критичных данных — AOF с appendfsync always (падение throughput с ~100k до ~10-20k ops/sec).
MongoDB и MySQL: кратко
MongoDB Replica Set из трёх нод — стандарт. Проблема: writeConcern: { w: 1 } — данные могут потеряться при падении primary. На production мы настраиваем w: "majority" и j: true. Индексы строим по порядку ESR (Equality → Sort → Range), иначе IXSCAN с in-memory сортировкой.
MySQL в режиме Galera Cluster (Percona XtraDB Cluster) даёт synchronous multi-master, но убивает write-heavy нагрузку certification conflicts. Альтернатива — InnoDB ReplicaSet с MySQL Router и Group Replication: меньше гарантий, выше throughput.
Elasticsearch: управление индексами
Elasticsearch — не база данных. Попытки использовать его как таковую приводят к mapping explosions при dynamic: true. Мы отключаем dynamic, явно маппим поля и настраиваем ILM для time-series данных (rollover по 50GB/1 день, forcemerge в warm, freeze в cold, delete через 90 дней).
Как мы настраиваем database layer: процесс и результаты
Наш процесс включает четыре этапа:
-
Аудит — собираем
pg_stat_statements,SHOW STATUS LIKE 'Innodb%', проверяем репликацию, бекапы, connection pooling, версии СУБД. - Проектирование — выбираем топологию HA (Patroni, Redis Cluster, ReplicaSet), настраиваем DCS, мониторинг, alerting.
- Реализация — разворачиваем кластер, настраиваем PgBouncer, бэкапы (pgBackRest, WAL-G), тестируем failover.
- Документация и передача — отдаём topology diagram, runbook failover, процедуру восстановления с реальными RTO/RPO, доступы к мониторингу.
Дополнительно: что входит в результат
- Полностью работоспособный HA-кластер PostgreSQL с автоматическим failover
- PgBouncer с транзакционным пулингом, настроенный под нагрузку
- Мониторинг ключевых метрик (lag, connection count, disk usage, WAL generation) через Prometheus + Grafana
- Runbook для типовых операций (ручной failover, восстановление из бекапа, добавление ноды)
- Скрипты бэкапов с проверкой целостности (pg_verifybackup)
- Рекомендации по репликации и шардингу для MongoDB/Redis
- Сопровождение после настройки: 2 недели реактивной поддержки
| Задача | Срок |
|---|---|
| Аудит PostgreSQL + рекомендации | 2–3 дня |
| Настройка Patroni HA (3 ноды) | 3–5 дней |
| Redis Cluster (6 нод) | 2–4 дня |
| PgBouncer + оптимизация запросов | 3–5 дней |
| MongoDB Replica Set + мониторинг | 2–4 дня |
| Комплексный database layer (несколько СУБД) | 2–4 недели |
Стоимость рассчитывается индивидуально после аудита инфраструктуры. Типичный проект по настройке PostgreSQL HA для интернет-магазина с 10 млн заказов в месяц помог клиенту сэкономить $18k–26k в год на переплате за облачные инстансы (до этого держали 4 standalone БД для отказоустойчивости, после миграции на Patroni с 3 нодами снизили затраты на 40%).
Оценим ваш проект — свяжитесь с нами, чтобы получить консультацию и предварительный расчёт. Закажите аудит базы данных под ключ: за 2 дня вы получите список проблем и план их устранения.
Ссылки: Patroni documentation · PostgreSQL replication slots (Wikipedia)







