feat(ops): DR-тест восстановления бэкапа PG + runbook HA/DR
Закрыта слепая зона «бэкапы есть, но восстановление не проверялось». - scripts/ops/pg_restore_verify.sh — берёт последний дамп из MinIO backups/pg/, restore в ЭФЕМЕРНЫЙ postgres:16, проверяет ключевые таблицы (users/documents/ tasks). Прод не трогает, всё в одноразовом контейнере. Под cron раз в неделю. - docs/DR-HA.md — runbook: бэкапы, проверка восстановления, потоковая репликация PG, Redis-реплика+Sentinel, таблица SPOF со статусом митигаций. Провижн реплик PG/Redis — на Proxmox (нужен новый LXC), это работа на железе, не в репозитории; runbook даёт конкретные шаги. Векторный SPOF уже снимается Qdrant. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
55
docs/DR-HA.md
Normal file
55
docs/DR-HA.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Отказоустойчивость и восстановление (HA / DR)
|
||||
|
||||
Актуальная топология: PostgreSQL на выделенном LXC **1.38**, Redis на **1.35**,
|
||||
RabbitMQ на **192.168.20.82**, app+ES на **1.32**. Это не docker-compose, поэтому
|
||||
HA для БД/кэша делается на уровне Proxmox/LXC, а не в этом репозитории.
|
||||
|
||||
## 1. Бэкапы (сделано)
|
||||
|
||||
`pg_dump → gzip → MinIO backups/pg/`, cron ежедневно 03:00 на 1.38, ротация 14 дней.
|
||||
|
||||
## 2. Проверка восстановимости (сделано — было слепой зоной)
|
||||
|
||||
Бэкап без проверенного восстановления = отсутствие бэкапа. Скрипт
|
||||
[`scripts/ops/pg_restore_verify.sh`](../scripts/ops/pg_restore_verify.sh) берёт
|
||||
последний дамп из MinIO, restore в **эфемерный** `postgres:16` и проверяет ключевые
|
||||
таблицы. Прод не трогает.
|
||||
|
||||
```bash
|
||||
bash scripts/ops/pg_restore_verify.sh # креды из .env
|
||||
```
|
||||
|
||||
Рекомендация: cron раз в неделю на 1.32, алерт (как в antiplag_monitor) при ненулевом коде.
|
||||
|
||||
## 3. HA PostgreSQL — потоковая репликация (требует новый LXC)
|
||||
|
||||
Провижн реплики — задача на Proxmox (нужен ещё один LXC, напр. 1.39). Шаги:
|
||||
|
||||
1. **Primary (1.38)** `postgresql.conf`: `wal_level=replica`, `max_wal_senders=5`,
|
||||
`wal_keep_size=1GB`; `pg_hba.conf`: строка `replication` для IP реплики.
|
||||
2. **Replica**: `pg_basebackup -h 1.38 -U replicator -D $PGDATA -R` (создаёт
|
||||
`standby.signal` + `primary_conninfo`), затем старт — догоняет primary по WAL.
|
||||
3. **Failover**: ручной `pg_ctl promote` на реплике + переключение `POSTGRES_HOST`
|
||||
в `.env` (или автоматизация через Patroni + etcd — если нужен авто-failover).
|
||||
4. Проверка лага: `SELECT * FROM pg_stat_replication` на primary.
|
||||
|
||||
## 4. HA Redis — реплика + Sentinel (требует новый LXC)
|
||||
|
||||
Redis у нас — кэш/rate-limits/LSH-индекс (префикс `antiplag_lsh`). Потеря = деградация,
|
||||
не потеря данных задач (они в PG). Если нужна устойчивость:
|
||||
|
||||
1. Второй Redis (реплика): `replicaof 1.35 6379` + тот же `requirepass`.
|
||||
2. **3× Sentinel** (на app-хостах): `sentinel monitor antiplag 1.35 6379 2`,
|
||||
авто-переключение мастера.
|
||||
3. Клиенты (Celery/кэш) → на Sentinel-aware подключение (`redis.sentinel`),
|
||||
либо оставить прямое подключение + ручной перевод `REDIS_URL` при аварии.
|
||||
|
||||
## 5. Единые точки отказа — статус
|
||||
|
||||
| Компонент | SPOF | Митигация |
|
||||
|-----------|:----:|-----------|
|
||||
| PostgreSQL 1.38 | да | бэкап+restore-тест ✅; реплика — §3 (нужен LXC) |
|
||||
| Redis 1.35 | да | graceful-фолбэк LSH в память ✅; реплика+Sentinel — §4 |
|
||||
| Векторный индекс | было | `VECTOR_BACKEND=qdrant` снимает (см. README) ✅ |
|
||||
| RabbitMQ .82 | да | мониторинг ловит падение ✅; кластер — по потребности |
|
||||
| app/ES 1.32 | да | воркеры горизонтальны; ES single-node (для BM25 не критично) |
|
||||
Reference in New Issue
Block a user