0046. Размер объекта без фиксированного предела и адаптивные части multipart
Статус: accepted. Дата: 2026-09-30. Развивает ADR 0007 и ADR 0029.
Контекст
Хранилище принимает артефакты десятков гигабайт и больше: сборки, образы, наборы контента. Прежде размер ограничивали сразу несколько несогласованных чисел: 64 GiB на сервере, 5 GiB в SDK-скачивании, CLI-загрузке, веб-staging, вложениях и импорте. Часть фиксировалась в 8 MiB, а частей могло быть не больше 10 000, поэтому раскладка физически адресовала лишь около 78 GiB. Каталог дополнительно отказывал после 100 000 записей, включая удалённые. Файл, загруженный через веб, мог стать нескачиваемым собственными клиентами.
Решение
- Фиксированного продуктового предела размера объекта нет. Верхняя граница — предел multipart-раскладки: 10 000 частей по 1 GiB (
MAX_OBJECT_BYTES≈ 10 TiB). Оператор может задать меньшийARKVORY_MAX_OBJECT_BYTES. Фактические границы — квоты репозитория,ARKVORY_CAPACITY_BYTESи свободное место. - Размер части выбирается при создании загрузки: 8 MiB или ближайшая степень двойки, при которой частей не больше 10 000. Он хранится в
arkvory_uploads.part_bytes(миграция 21) и возвращается вGET uploads/{id}/parts. Существующие сессии сохраняют 8 MiB. Клиент хеширует одну часть в памяти, поэтому раскладка сначала увеличивает число частей, а затем их размер. GET /api/v1/capabilitiesсообщаетmaxObjectBytes,partBytes(минимум),maxPartBytesиmaxParts. SDK, CLI, импорт и веб-консоль не содержат собственных пределов размера. Веб-консоль проверяет лимит сервера до хеширования, staging скачивания ограничен квотой браузера.- Поиск существующей части выполняется точечным запросом: загрузка из 10 000 частей остаётся линейной.
- Сборка больших объектов может длиться дольше одного HTTP-запроса. Для файлов от 16 GiB SDK завершает загрузку через
complete-asyncи worker и опрашивает задание. Задание, упавшее по временной причине (потеря lease, недоступность БД или хранилища), владелец может поставить в очередь повторно без новой загрузки байтов. - Каталог не ограничивает число записей. Ёмкость считает только неосвобождённые байты.
Альтернативы
- Поднять фиксированный предел до 1 TiB: снова одно произвольное число, которое расходится между компонентами.
- Увеличить число частей при 8 MiB: списки частей становятся слишком большими для resume, а раскладка всё равно упирается в предел.
- Потоковое хеширование части в SDK: в браузере Web Crypto не поддерживает инкрементальный SHA-256; отдельная реализация возможна позже, если понадобятся части больше 1 GiB.
Последствия
- Для файла размера N во время сборки нужен запас около 2N: части хранятся до GC.
- Одиночный PUT по-прежнему ограничен
ARKVORY_UPLOAD_DEADLINE_MS; для больших файлов обязателен multipart (SDK и CLI выбирают его сами). - Реальная передача проверяется сценариями 5 GiB; раскладка выше 78 GiB подтверждается unit и PostgreSQL/HTTP тестами. Передачу десятков гигабайт на целевом оборудовании нужно измерить отдельно.
Проверка
- Unit:
partBytesForдля границ 8 MiB × 10 000 и предела раскладки, валидацияpartBytes, покрытие частей с нестандартным размером, SDK-завершение через worker. - PostgreSQL/HTTP: сессия 100 GiB получает части 16 MiB, неверный размер части отклоняется, лимит оператора отказывает до передачи байтов, временно упавшее задание ставится повторно, постоянная ошибка — нет, миграция 21 повторяема.