docs(runbooks): ранбуки-файлы → стубы с указателями [[wiki:N]] (канал файлов закрыт) — task:1507

18 runbook-файлов .wiki/concepts/ заменены на стубы-указатели на mappa wiki-сущности.
5 без дубля заингестены в mappa: wiki:3329-3333 (gitea-project-create, pilorama98-vds-deploy,
sched-pipelines-local-stack, sched-publish, sched-vds-deploy). Индекс wiki:3316 переведён на wiki-ссылки.
This commit is contained in:
2026-08-29 11:13:47 +03:00
parent b6e0e776e8
commit 6547558833
18 changed files with 36 additions and 2193 deletions

View File

@@ -1,102 +1,3 @@
---
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` (стек 33, `/usr/docker/elasticsearch/docker-compose.yml`, `ES_JAVA_OPTS=-Xmx256m`),
`bookva-es` (**Portainer стек 37, endpoint 1**; `ES_JAVA_OPTS` урезан 512m→`-Xmx256m`).
- **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=-Xms512m -Xmx512m``-Xms256m -Xmx256m`.
Сделано: Portainer PUT стека 37 (`PUT /api/stacks/37?endpointId=1` с реконструированным compose). Verify: `docker logs bookva-es | grep heap``heap size [256mb]`.
### 4. `minio` / `bookva-minio` / `books-ops-mcp` — cgroup-потолки памяти
Реконструкция compose вслепую рискованна (данные minio-тома, files-секреты, сеть) → `docker update --memory` (без пересоздания):
```bash
docker update --memory 512m --memory-swap 512m minio
docker update --memory 384m --memory-swap 384m bookva-minio
# books-ops-mcp (Node) — 'memory.memsw.limit_in_bytes: device or resource busy' (cgroup v1) — не применилось.
```
Потолки (защита от раздувания в пик; не освобождают текущие буферы).
## 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. **Книги-стеки — через `portainer.kzntsv.site` endpoint 1 (= books VDS)**: `GET /api/stacks` показывает id 2251 (books/web/api/ntfy/ops-mcp/chrome/proxy/imgproxy/minio/mongo/db/elasticsearch + bookva-*). Часть из них — **files-based** `/usr/docker/*/docker-compose.yml` (напр. books-job-scheduler-mongo урезан файлом + `docker compose up -d`). При правке стека держать 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`** — **Portainer стек 37 (endpoint 1)**. Доступ есть: `BOOKS_PORTAINER_URL` + `BOOKS_PORTAINER_API_KEY` из `pass books-vds/full-env`. НО `GET /api/stacks/:id` НЕ отдаёт `stackFileContent` (в этой версии Portainer), поэтому compose реконструируется из `docker inspect` и обновляется через `PUT` стека. Не менять вслепую без этих данных.
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) и бэкапы. Отдельная задача/ранбук.
**Не читать. Не править.** Канон — mappa wiki-сущность [[wiki:3304]] (concepts/books-vds-memory-optimize-runbook). Скил: `admin-runbooks` / `mappa-knowledge`.