Files
invest-harness/designDocument/scaling.md
T

7.9 KiB
Raw Blame History

Масштабирование 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.