59 lines
7.9 KiB
Markdown
59 lines
7.9 KiB
Markdown
# Масштабирование Invest Harness
|
||
|
||
## Модель нагрузки
|
||
|
||
Число аккаунтов не определяет ёмкость. Измеряем arrival rate λ, среднюю и p95 длительность T, CPU и память Attempt, размер образа, объём логов, количество внешних запросов и число одновременных подключений. Раздельные классы: короткие интерактивные задачи, длинные фоновые, периодические и сборка пакетов.
|
||
|
||
По Little’s law среднее число активных задач L = λ × T. Для целевой загрузки слотов ρ начальная оценка slots ≥ λ × T / ρ. Пример-гипотеза: 120 запусков/мин, 180 секунд на запуск, ρ=0.7 → около 515 слотов. Это не 515 серверов: число слотов на узле ограничено одновременно CPU, RAM, диском и квотами API. Хвосты длительности требуют нагрузочного измерения, а не подстановки p95 в доказательство SLO.
|
||
|
||
## Очереди и backpressure
|
||
|
||
Admission control резервирует tenant concurrency и бюджет перед назначением. Weighted fair scheduling чередует tenants; внутри tenant приоритет + возраст. Ограничены queue depth и max queue age. При превышении пользователь получает 429 с Retry-After либо явный queued status по принятой policy. Бесконечного скрытого backlog быть не должно.
|
||
|
||
Учитываем лимиты внешних API, токены/мин, соединения и доступность источников. Шлюз контролирует свои вызовы. Для прямых вызовов Runner платформа гарантирует только ресурсные/временные лимиты, а финансовый предел зависит от провайдера credentials.
|
||
|
||
## Масштабирование компонентов
|
||
|
||
| Компонент | Стратегия | Ограничение |
|
||
|---|---|---|
|
||
| Stateless API и каталог | Несколько реплик за Gateway | Пулы SQL и согласованность прав |
|
||
| Диспетчер | Atomic claims, partitioning по tenant/pool | Единственное назначение Attempt и fencing |
|
||
| Сервис исполнения | Сначала ресурсы и отдельные пулы, затем проверенное шардирование | Нельзя предполагать поддержку active-active ядром |
|
||
| Runner | Масштабирование по ready queue age и свободным ресурсам | Внешние API и время загрузки образа |
|
||
| PostgreSQL | Индексы, bounded pagination, архивирование; read replicas для допустимо устаревших чтений | Назначения и авторизация читаются из актуального источника |
|
||
| S3 / registry | Прямые scoped grants, кеш по digest, лимит параллельных загрузок | Bandwidth, egress, cache isolation |
|
||
|
||
Горячие индексы: Run(tenantId, createdAt, id), Run(status, nextEligibleAt, id), Attempt(poolId, leaseUntil), Package(tenantId, kind, name), уникальный PackageVersion(packageId, version). Большие события и логи не хранятся целиком в строке Run.
|
||
|
||
## Прогрев и масштабирование исполнителей
|
||
|
||
Managed pool хранит небольшой warm reserve. Scale-out — по времени ожидания совместимых задач, scale-in — после drain: новые задания не выдаются, активные завершаются. Кеш неизменяемых образов по digest экономит загрузки. Приватные образы и архивы не выдаются другому tenant без проверки доступа. Garbage collection кеша использует размер и last-used; pinned active layers не удаляются.
|
||
|
||
Собственный пул имеет независимые лимиты и SLA владельца. Недоступность такого пула не переносит задание автоматически в управляемый: credentials и политика размещения могут запрещать перенос.
|
||
|
||
## Отказы
|
||
|
||
| Сбой | Поведение |
|
||
|---|---|
|
||
| API после записи Run | Повтор Idempotency-Key возвращает прежний Run |
|
||
| Dispatcher после отправки job | Reconcile по attemptId, без второго внешнего запуска |
|
||
| Runner потерял связь | Lease expires → interrupted; retry только по policy |
|
||
| S3 недоступен при завершении | Нет succeeded до проверки ResultManifest |
|
||
| Catalog недоступен | Новые resolve ждут/ошибка; закреплённые запускать только при актуальной policy |
|
||
| Registry недоступен | Кеш допустим при проверке digest и актуальных прав; иначе очередь |
|
||
| SQL недоступен | Новые назначения остановлены; terminal reports повторяются идемпотентно |
|
||
|
||
## Retention и восстановление
|
||
|
||
Исходные настраиваемые значения: orphan uploads 24 часа; debug-логи 14 дней; результаты 30 дней; аудит 180 дней. Это проектные значения, а не юридические обязательства. Активные Run и checkpoints защищены от очистки. Образы удаляются только после проверки ссылок, grace period и доступности backup.
|
||
|
||
Backup включает БД, объекты, ключевые конфигурации и возможность восстановления ключей шифрования. Проверяется согласованное восстановление metadata → digest → object. Цели для первой проверки: RPO 1 час, RTO 4 часа, без обещания до rehearsal.
|
||
|
||
## Метрики и проверка
|
||
|
||
Предлагаемые цели пилота: p95 control API <500 мс без внешних вызовов; p95 queue wait <30 секунд при нагрузке в пределах квоты и доступном пуле. Время выполнения чёрного ящика не включается в API SLO. Следим за queue age, interrupted rate, attempts/run, event lag, orphan bytes, cache hit, SQL saturation и стоимостью на Run.
|
||
|
||
Нагрузочные сценарии: равномерный поток, массовый scheduled burst с jitter, один шумный tenant, недоступный внешний API, перезапуск dispatcher, потеря Runner, медленный S3, дубли terminal reports. Отдельно проверяем отсутствие чужих артефактов и credentials.
|
||
|
||
Стоимость = вычисления + хранение + egress + управляемые вызовы моделей. Цена прямых сторонних вызовов может быть неизвестна. Биллинг не строится исключительно на недоверенных отчётах пользовательского Runner.
|