diff --git a/.wiki/concepts/books-vds-memory-optimize-runbook.md b/.wiki/concepts/books-vds-memory-optimize-runbook.md new file mode 100644 index 0000000..f2b7706 --- /dev/null +++ b/.wiki/concepts/books-vds-memory-optimize-runbook.md @@ -0,0 +1,92 @@ +--- +title: "books VDS — оптимизация памяти (mongo wiredTiger / ES heap / CI-остатки)" +type: concept +tags: [runbook, books, vds, mongo, elasticsearch, oom, memory, backup, admin] +related: [concepts/runbooks-index.md, concepts/gitea-project-create-runbook.md] +updated: 2026-08-28 +--- + +# books VDS — оптимизация памяти (OOM → ECONNREFUSED) + +> **⚙️ СЛУЖЕБНЫЙ РАНБУК — только для администратора проекта `.admin`.** +> Применять/выполнять шаги может только **`.admin`** (оператор проекта admin). Другим проектам/агентам — читать по запросу, не выполнять. +> Из проекта не выносить: не копировать в другие вики, не пересказывать, не публиковать. +> Нужен деплой или прод-операция по этому ранбуку — **поставить задачу админу (`.admin`) и написать письмо**. Админ выполняет, остальные верифицируют. + +## Scope + +Остановить **OOM-цикл** на books VDS (`89.253.255.133`, host4g VPS, CentOS 7), который +вызывает `[sched:slovo] sync.failed: ECONNREFUSED 172.20.0.5:27017`. Причина — дефицит ОЗУ: +хост 3.9GB RAM, free ~136MB, **swap 100%**, OOM-kill `mongod` (dmesg `Out of memory: Kill +process (mongod) score ~114`). Симптом-задача — «ozon fbs products syncronization» (books-sched, прод slovo). + +## Артефакты + +- **Хост:** `89.253.255.133` (books VDS). SSH: `ssh -i ~/.ssh/id_ed25519_books_ops root@89.253.255.133`. +- **Креды:** `<из pass books-vds/full-env>` (`BOOKS_DB_*`, `BOOKS_MONGO_*`, `BOOKS_PORTAINER_*`). +- **mongo (БД sched):** `books-job-scheduler-mongo` = `172.20.0.5:27017`, image `mongo:4.2`, + БД `agendaDb` (sched-задачи: `sched_tasks`, `sched_schedules`, `sched_runs`). Source-of-truth compose: + `/usr/docker/books-job-scheduler/docker-compose.yml` (**files-based**, НЕ Portainer-kzntsv). +- **ES:** `elasticsearch` (`/usr/docker/elasticsearch/docker-compose.yml`, `ES_JAVA_OPTS=-Xmx256m`), + `bookva-es` (Portainer/hidden — см. gotchas, `ES_JAVA_OPTS=-Xmx512m`). +- **CI-остатки:** `buildx_buildkit_builder-*` (`moby/buildkit:buildx-stable-1`), удалены. + +## Диагностика (как понять, что это OOM) + +```bash +ssh root@89.253.255.133 ' + free -m; dmesg | grep -iE "oom|killed process" | tail; # free ~136MB, swap 100%, Killed (mongod) + docker stats --no-stream --format "{{.MemUsage}}\t{{.Name}}" | sort -rh | head; # кто жрёт +' +``` +Кто жрёт (на 2026-08-28): `books-job-scheduler-mongo` 715MiB (главный), `minio` 248+140, `elasticsearch` 242, `bookva-es` 223. + +## Шаги (по порядку эффекта) + +### 1. Урезать `books-job-scheduler-mongo` wiredTiger (главный фикс, ~+450MB) +```bash +cd /usr/docker/books-job-scheduler +cp docker-compose.yml docker-compose.yml.bak +# вставить после " restart: always" в сервисе books-job-scheduler-mongo: +# command: ["mongod", "--wiredTigerCacheSizeGB", "0.25"] +docker compose up -d books-job-scheduler-mongo +``` +Verify: `docker logs books-job-scheduler-mongo | grep -i "cache_size"` → `cache_size=256M`; +`docker exec books-job-scheduler-mongo mongo --quiet --eval "db.runCommand({ping:1}).ok"` = 1. + +### 2. Снести CI-остатки `buildx_buildkit_builder-*` (сироты от CI) +```bash +docker rm -f buildx_buildkit_builder-1ba06752-bf56-4b50-88c5-ce1b48f44a4e0 buildx_buildkit_builder-f61c259c-48e3-4401-b2ca-2404c5cd76070 +``` + +### 3. Урезать ES heap (вторично; elasticsearch уже 256m) +`bookva-es` → `ES_JAVA_OPTS=-Xms256m -Xmx256m` (через его деплой; см. gotchas). + +## Verify / smoke + +- `free -m` — free растёт, swap падает (mongo cache_size=256M). +- Нет новых `Out of memory: Kill (mongod)` в dmesg на следующем окне (~06:06). +- `docker stats` — `books-job-scheduler-mongo` ≪715MiB. +- sched-задачи (`ozon fbs products syncronization`) больше не дают `ECONNREFUSED 172.20.0.5:27017`. + +## Rollback + +- mongo: `git checkout`-возврат `command` в compose (или `cp docker-compose.yml.bak docker-compose.yml`) → `docker compose up -d books-job-scheduler-mongo`. +- ES: вернуть `ES_JAVA_OPTS`. + +## Gotchas + +1. **OOM ежедневно ~06:06** — пик в бэкап-окно (mongodump+mariadb-dump+ES snapshot в 06:00 MSK). Урезка снижает, но ХОСТ обделён (3.9GB) — радикальный фикс = апгрейд RAM или Manticore вместо ES. +2. **Управление books VDS — файловые compose** `/usr/docker/*/docker-compose.yml`, НЕ Portainer-kzntsv. `portainer.kzntsv.site` endpoints — только `primary`+`stostayer`, книг там нет. Свой Portainer на books VDS — без host-port (нестандартно), напрямую не доступен. **Канон kzntsv «всё через Portainer» на книги не распространяется.** +3. **`com.docker.compose.project.config_files=/data/compose/22`** (label) — старый путь Portainer; `/data/compose/*` на диске НЕ существует. Реальный источник — `/usr/docker/*/docker-compose.yml`. +4. **compose-файлы в CRLF** (`\r\n`) — python-патч учитывать line-ending (иначе needle не матчит). +5. **`bookva-es`** — deploy неоднозначен (нет локального compose, `/data/compose/37` нет; управляется скрытым механизмом) — править осторожно, только при понимании деплоя. +6. **mongo warning XFS** — предупреждение, не ошибка (данные на ext4). +7. **`command` массив** в compose: `command: ["mongod", "--wiredTigerCacheSizeGB", "0.25"]` — строку тоже можно, но список надёжнее. + +## Будущее направление — замена ES → Manticore + +ES в стеке книг — источник перегруза (Java JVM). **Manticore Search** — без Java, легче +(сотни MB против 500+MB), быстрее на полнотекстовом поиске. Оправдано, если ES используется +для полнотекстового поиска товаров/книг (не анализа/DSL-агрегаций). Тогда урезать оба ES, +переписать поиск на Manticore-протокол (SphinxQL/HTTP) и бэкапы. Отдельная задача/ранбук. diff --git a/.wiki/concepts/runbooks-index.md b/.wiki/concepts/runbooks-index.md index 46cc7dc..18627a4 100644 --- a/.wiki/concepts/runbooks-index.md +++ b/.wiki/concepts/runbooks-index.md @@ -47,6 +47,7 @@ updated: 2026-08-26 | Операция | Ранбук | Что покрывает | |---|---|---| | Создание Gitea-репо (проект в Gitea) | [`gitea-project-create-runbook.md`](gitea-project-create-runbook.md) | private-репо: admin POST /user/repos → transfer к владельцу; pre-flight; verify; rollback; gotchas (SSH-порт 2222, pass-рефы) | +| books VDS — оптимизация памяти (OOM → ECONNREFUSED) | [`books-vds-memory-optimize-runbook.md`](books-vds-memory-optimize-runbook.md) | mongo wiredTiger 0.25 / ES heap / CI-остатки buildx; files-compose (НЕ Portainer-kzntsv); verify; rollback; Manticore-задел | | MinIO split (books-vds + CMS-media) | [`minio-split-cutover-runbook.md`](minio-split-cutover-runbook.md) | cutover Track A/B, rollback | | Общий Portainer-канон VDS kzntsv | [`portainer-stack-management-vds.md`](portainer-stack-management-vds.md) | JWT auth, gotchas 1-10, redeploy-рецепт, инвентарь стеков | | Политика деплоя mappa | [`deploy-policy-mappa.md`](deploy-policy-mappa.md) | кто деплоит, канон таска+письмо |