From c17fca792cd5987a706609dcce298663242a4caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Sun, 23 Aug 2026 11:11:47 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D1=80=D0=B5=D0=B7=D1=83=D0=BB=D1=8C?= =?UTF-8?q?=D1=82=D0=B0=D1=82=D1=8B=20edge-case=20=D0=B8=20=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=B5=D1=81=D1=81-=D1=82=D0=B5=D1=81=D1=82=D0=B0=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D0=B8=20(v0.0.59?= =?UTF-8?q?=E2=80=930.0.60,=20OOM=20=D0=BD=D0=B0=204Gi,=20=D0=B4=D0=B5?= =?UTF-8?q?=D0=B4=D1=83=D0=BF,=20=D0=BB=D0=B8=D0=BC=D0=B8=D1=82=D1=8B)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- History/2026-08-23-upload-stress-test.md | 55 ++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 History/2026-08-23-upload-stress-test.md diff --git a/History/2026-08-23-upload-stress-test.md b/History/2026-08-23-upload-stress-test.md new file mode 100644 index 0000000..85fa866 --- /dev/null +++ b/History/2026-08-23-upload-stress-test.md @@ -0,0 +1,55 @@ +# drhider — тесты загрузки и стресс (2026-08-23, v0.0.59–0.0.60) + +_Платформа: Штурвал, кластер `naeel-test-3` (kubeconfig `~/.kube/config-naeel-test-3` на ВМ). +ВМ-буфер: `https://contracts.kube5s.ru/drhider-upload/` (nginx dav). Тест-режим: `?upload-only=1`._ + +## Изменения за день +- **v0.0.58** — ВМ-загрузка: PUT на ВМ + `/api/upload_refs` (egress pull) + тест-режим `?upload-only=1`. +- **v0.0.59** — убран лимит 100 МБ/файл (фронт; остался суммарный 1 ГБ). +- **v0.0.60** — дедуп по **имя+размер** (дату игнорируем), при совпадении остаётся **более свежий**. + +## Edge-case тесты (v0.0.59, браузер/Playwright) +- Нулевой размер (`empty.txt` 0 B) — принимается, грузится (0 B/s), в сессии size=0. ✅ +- Бинарный файл (`bin.dat`) — принимается, грузится. ✅ +- Одинаковое имя, разный размер — суффикс `_2`. ✅ +- Одинаковые имя+размер, разная дата — **дедуп** (было `_2`, с v0.0.60 — один, свежий). ✅ +- Один файл в архиве и отдельно — **дедуп** (было `_2` из-за mtime, с v0.0.60 — один). ✅ + +## Стресс-тест загрузки (v0.0.60) +Под: `pythonk8s-8dbc866bb-d84p6`, requests/limits **cpu 2 / memory 4Gi**. +Путь: PUT на ВМ → `POST /api/upload_refs` (один JSON со всеми refs) → `GET /api/session_files`. + +### Сессии (11 успешных + 1 OOM) +| Сес. | Файлов | Объём | PUT | refs | +|---|---|---|---|---| +| A | 120 | 364МБ | 34.4с | 37.8с | +| B | 120 | 316МБ | 29.9с | 33.3с | +| C | 1×250МБ | 250МБ | 23.2с | 23.9с | +| D | 120 | 378МБ | 40.0с | 41.6с | +| E | 120 | 301МБ | 26.7с | 31.5с | +| F | 1×200МБ | 200МБ | 18.9с | 33.8с | +| G | 120 | 360МБ | 34.8с | 36.4с | +| H | 120 | 309МБ | 29.0с | 38.4с | +| I | 1×250МБ | 250МБ | 23.2с | 24.1с | +| J | 120 | 357МБ | 33.4с | 37.9с | +| K | 120 | 366МБ | 34.3с | 40.1с | +| **L** | 120 | 369МБ | — | **FAIL (OOM)** | +| M | 120 | 347МБ | 32.5с | 36.0с (после рестарта) | +| N | 120 | 358МБ | 33.1с | 37.5с (после рестарта) | + +### Память пода (рост линейный, ~1.2× объёма сессий) +55Mi (база) → 744Mi (3 сес.) → 1991Mi (6 сес.) → 3235Mi (9 сес., ~80% лимита) → **OOMKilled на L**. + +### Итог OOM +- `restarts=1, lastReason=OOMKilled, exitCode=137` (лимит 4Gi). +- После авто-рестарта под работает, загрузка продолжается (M, N ok). +- **Все сессии A–L потеряны** (in-memory хранилище, TTL 30 мин, без персиста). + +## Выводы / факты +1. Загрузка через ВМ стабильна на больших объёмах: до OOM — 11 сессий ~3.3ГБ, 0 ошибок, скорость не деградирует. +2. Потолок памяти = лимит пода 4Gi; OOM при ~3.5ГБ резидентных сессий. +3. Апп переживает OOM (рестарт + продолжение работы), но сессии теряются. +4. Код: `session.py MAX_SESSION_BYTES = 500МБ` (на сессию) — OOM реален только при ~8+ одновременных сессий. +5. `upload_refs` при переполнении сессии отвечает 404 «Session not found» (вводит в заблуждение — это лимит размера). +6. ГРАБЛЯ: на Krupski `dd` алиасится на `docker compose down`; прокси `172.17.192.1:10808` — тесты только `--noproxy '*'`/`NO_PROXY`. +7. Браузер-автоматизация (Playwright) видит Windows-ФС (`C:\tmp\...`) — тестовые файлы класть в `/mnt/c/tmp/` (WSL).