Files
admin/.wiki/concepts/books-vds-memory-optimize-runbook.md

94 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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]`.
## 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`** — **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) и бэкапы. Отдельная задача/ранбук.