diff --git a/docs/DR-HA.md b/docs/DR-HA.md index 30fcb08..d6cf033 100644 --- a/docs/DR-HA.md +++ b/docs/DR-HA.md @@ -30,7 +30,9 @@ bash scripts/ops/pg_restore_verify.sh # креды из .env 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). + в Infisical (окружение `prod` — не в `.env` на сервере напрямую, его перезапишет + следующий деплой, см. ARCHITECTURE.md §10) и передеплой/рестарт сервисов + (или автоматизация через Patroni + etcd — если нужен авто-failover). 4. Проверка лага: `SELECT * FROM pg_stat_replication` на primary. ## 4. HA Redis — реплика + Sentinel (требует новый LXC) @@ -53,3 +55,19 @@ Redis у нас — кэш/rate-limits/LSH-индекс (префикс `antipla | Векторный индекс | было | `VECTOR_BACKEND=qdrant` снимает (см. README) ✅ | | RabbitMQ .82 | да | мониторинг ловит падение ✅; кластер — по потребности | | app/ES 1.32 | да | воркеры горизонтальны; ES single-node (для BM25 не критично) | + +## 6. Известный операционный риск — RabbitMQ `consumer_timeout` vs долгие таски + +Обнаружено на практике (2026-08-26): RabbitMQ по умолчанию рвёт канал, если consumer +не сделал ack за 1800с. Любой Celery-таск с retry-логикой (rate-limit backoff у +парсеров, ожидание зависшего внешнего сервиса вроде Ollama), суммарно занимающий +дольше — брокер обрывает соединение раньше, чем таск успевает сдаться и +подтвердиться, весь Celery-процесс падает (`exitCode=1`), Docker +(`restart: unless-stopped`) поднимает его заново, недоставленное сообщение +передоставляется — и цикл повторяется бесконечно, монополизируя весь пул воркера +(было и на `worker-indexer` из-за backoff `scripts/parsers/openalex.py`, и на +`worker-gpu` из-за зависшей Ollama на embedding-gpu). Текущая митигация — держать +retry-бэкоффы заведомо короче 1800с (пример: `MAX_RATE_LIMIT_RETRIES` в +`openalex.py`). Более глубокий фикс — поднять `consumer_timeout` на самом RabbitMQ +(доступа для этого пока не заводили) — актуально при добавлении любых новых +долгих retry-циклов в Celery-тасках.