Упаковка just-in-time против pre-packaged origin

Автор: Николай СапуновОбновлено: август 202632 мин чтения
Содержание статьи +

TL;DR

Стриминговый origin может хранить каталог в одной из двух форм. Форма pre-packaged один раз на ингесте пишет на диск каждый плейлист HLS, каждый MPD DASH и каждый короткий сегмент – и потом отдаёт их как статические HTTP-объекты навсегда. Форма упаковки just-in-time, сокращённо JIT или JITP, держит на диске один fragmented-MP4 мастер на каждую ступень bitrate-лесенки и синтезирует плейлисты, MPD и пер-протокольные виды сегментов на лету – в тот момент, когда плеер их запрашивает. JIT меняет хранилище на CPU origin'а – типично 3- до 5-кратная экономия storage против 5- до 20-кратного роста compute-нагрузки на origin – и приносит одно стратегическое преимущество, которого pre-packaging дать не может: новый протокол, новый нюанс упаковки или новое DRM-правило можно раскатать на каталог из тысячи тайтлов одним redeploy origin'а, а не перепаковкой каталога. Для стриминговой платформы 2026 года с парой сотен тайтлов и более JIT – это дефолт, а архитектура, в которую он вписан – CMAF-fMP4 мастер на каждую ступень, JIT origin за origin shield, CDN с длинными TTL на сегменты и короткими TTL на манифесты – это форма, к которой сходится любая серьёзная OTT-, спортивная или e-learning-платформа.

Кому и зачем это нужно

Упаковка – это та строка хранилища, на которую большинство продакт-менеджеров не смотрят, пока счёт AWS не утроится. Pre-packaged origin может незаметно умножить storage в двенадцать раз, как только вы добавите HLS, DASH, несколько аудио-дорожек и пару low-latency-вариантов, – и каждый гигабайт капает в счёт каждый месяц, смотрит ли его кто-нибудь или нет. JIT origin меняет эту строку storage на строку CPU origin'а, и новая строка хуже прогнозируется: она зависит от того, насколько cache-friendly построен путь JIT, как настроен CDN, стоит ли впереди origin shield и сколько catch-up-трафика переживает cache miss. Выберете не ту форму – переплатите либо за хранилище, которое никто не смотрит, либо за compute, которое могло бы поглотить одно правило кеша. Эта статья объясняет обе формы с нуля, даёт реальную арифметику, по которой между ними выбирают, и показывает архитектуру, которая нужна каждому JIT-деплою, чтобы быть cache-friendly настолько, чтобы выгода от обмена реально работала.

Что хранит стриминговый origin

Прежде чем говорить о том, как origin упаковывает контент, нужна чёткая картина того, что origin вообще есть. Стриминговый origin – это HTTP-сервер, с которым CDN общается, когда у edge-кешей ещё нет файла, который попросил зритель. Origin – источник истины: каждый байт, который зритель в итоге воспроизвёл, изначально пришёл оттуда. CDN копирует байты с origin'а в edge-серверы и отдаёт их зрителям с edge'ев, расположенных рядом с телефоном или ТВ зрителя. (Обзор окружающего пайплайна – в статье Конвейер стриминга от и до.)

Работа origin'а – отвечать на два вида HTTP-запросов. Первый – запрос манифеста, того маленького текстового файла, который перечисляет все ступени качества, между которыми плеер может переключаться, все короткие сегменты внутри каждой ступени и любые альтернативы аудио или субтитров. Манифесты HLS – текстовые .m3u8; манифесты DASH – XML-файлы .mpd. Второй вид – запрос сегмента, бинарного куска видео или аудио на 2–6 секунд, обёрнутого в контейнер (почти всегда fragmented MP4, сокращённо fMP4), который плеер умеет декодировать независимо от любого другого сегмента.

То, как origin производит ответы на эти два вида запросов, и делит мир на pre-packaged и JIT. Обе формы возвращают одни и те же байты для одного и того же URL. Разница в том, когда эти байты были созданы.

Форма pre-packaged: всё – это файл

В pre-packaged origin каждый манифест и каждый сегмент – реальный файл, лежащий на реальном хранилище, записанный один раз на ингесте, никогда больше не пересчитываемый. Когда плеер просит /movie-42/playlist_1080p.m3u8, origin читает /movie-42/playlist_1080p.m3u8 с диска и отдаёт. Когда плеер просит /movie-42/segment_00042.m4s, origin читает /movie-42/segment_00042.m4s с диска и отдаёт. HTTP-слой не интересует, что за файлом стоит; для него это могла бы быть JPEG.

Упаковка происходит один раз, до прихода любого зрителя. Энкодер передаёт пакетайзеру (Shaka Packager, Bento4, FFmpeg с нужными флагами – см. Упаковка видео: подробный разбор) готовую лесенку кодированных mezzanine – один файл на ступень. Пакетайзер режет каждую mezzanine на короткие сегменты, пишет каждый сегмент в собственный файл, пишет HLS-плейлист со списком этих сегментов, пишет DASH MPD со списком тех же сегментов, опционально пишет вариант в MPEG-TS рядом с fMP4 для legacy-плееров, опционально пишет low-latency HLS-вариант с partial-сегментами, опционально шифрует каждый сегмент по Common Encryption – и заливает всё это в storage origin'а. Каждый зритель, который смотрит тайтл следующие десять лет, читает с тех же файлов.

Pre-packaged – это исходная форма. Любой статический HTTP-сервер случайно является pre-packaged стриминговым origin'ом: вы кладёте .m3u8 и .m4s в дерево директорий, направляете на это CDN – и обслуживаете миллионы зрителей. NGINX – это pre-packaged origin. S3-бакет за CloudFront – pre-packaged origin. Первое поколение HLS в 2009 году работало исключительно на pre-packaged origin'ах, потому что ничего другого не существовало.

Сильная сторона pre-packaging очевидна. На запрос не тратится compute упаковки; единственная задача origin'а – прочитать байты с диска и послать их в сокет, что есть самое дешёвое, самое кешируемое и самое скучное, что HTTP-сервер вообще умеет. CDN кеширует каждый URL при первом запросе любого зрителя – и любой следующий зритель в любой точке мира получает кешированную копию. Failure modes простые: если сегмента нет, плеер получает 404, и на этом всё.

Скрытая цена pre-packaging

Скрытая цена pre-packaging – умножение storage. Современная стриминговая платформа отдаёт не одну версию тайтла. Она отдаёт много.

Возьмём один 90-минутный фильм. Лесенка энкодера производит шесть ступеней: 240p, 360p, 480p, 720p, 1080p и 4K. Это первый множитель – шесть. Платформе нужен HLS для iOS, Safari и большинства смарт-ТВ, и DASH для Android, Chrome и остальных смарт-ТВ. Это второй множитель – два. Платформа поддерживает два языка аудио и один язык субтитров. Это третий множитель – небольшой, но не нулевой. Платформа также хочет low-latency HLS-вариант для near-live-тайтлов и MPEG-TS legacy-вариант для упрямого long tail старых Apple TV. Прибавьте ещё ×1.4 за это.

В худшем случае объём на диске на один тайтл выглядит так:

6 ступеней × 2 формата упаковки × 2 аудио-дорожки × 1.4 legacy/LL-множитель
= ~33.6 копий одного и того же контента на диске на один тайтл.

90-минутный 1080p-фильм с битрейтом ~5 Mbps – около 3.4 GB «по проводу». Умножьте на 33.6 – и тайтл занимает ~114 GB storage. Каталог из 1 000 тайтлов требует 114 TB. По цене AWS S3 Standard около $0.023 за GB-месяц это $2 622 в месяц, смотрит хоть кто-нибудь хоть один тайтл или нет. Прибавьте второй регион для отказоустойчивости – счёт удвоится.

Арифметика становится ещё хуже для long tail. Распределение Парето в видео-каталогах жестокое: типично 80% просмотров приходятся на 20% каталога, а у многих платформ половина каталога играет меньше десяти раз в месяц. Вы платите полную аренду storage за половину каталога, который не приносит ощутимой выручки. CDN не помогает, потому что storage сидит на origin'е, и origin платит независимо от того, кешируется ли что-то на CDN.

Это та боль, которую и придумали лечить JIT.

Форма JIT: один мастер, много видов

Origin с упаковкой just-in-time хранит каталог на диске в одной канонической форме – обычно один fragmented-MP4 файл на каждую ступень – и синтезирует каждый пер-протокольный вид по запросу. Раскладка mezzanine на диске маленькая: шесть fMP4 на тайтл (по одному на ступень), по одному инициализационному сегменту на язык аудио, опциональные sidecar-файлы для субтитров и небольшое описание-метаданные.

Когда плеер запрашивает /movie-42/index.m3u8, JIT origin читает sidx-боксы fMP4-файлов на диске, считает свежий HLS multi-variant playlist со списком доступных ступеней и отдаёт его. Когда плеер запрашивает variant-плейлист /movie-42/playlist_1080p.m3u8, JIT origin читает sidx-индекс fMP4, считает свежий HLS media playlist со списком URL сегментов и отдаёт его. Когда плеер запрашивает /movie-42/seg_00042.m4s, JIT origin открывает fMP4-файл 1080p, ищет байтовый диапазон, соответствующий 42-му сегменту, упаковывает эти байты в свежий .m4s с правильными боксами styp и moof под тот протокол, на который указывает URL, – и отдаёт.

Ключевой момент: на диск ничего не было записано ради ответа ни на один из этих запросов. Каталог на диске остался ровно таким же маленьким, каким был до прихода первого зрителя. Если миллион зрителей смотрят фильм 42, JIT origin посчитает один и тот же сегмент миллион раз – если только его не закеширует CDN, и в этом «если» вся история о том, как JIT делают экономичным (см. «Почему нужен shield» ниже).

Рис. 1. Pre-packaged origin умножает storage на количество протоколов, аудио-дорожек и legacy-вариантов. JIT origin держит один канонический мастер на ступень и считает каждый пер-протокольный вид в момент запроса.

Та же арифметика из предыдущего раздела, пересчитанная для JIT:

6 ступеней × 1 формат упаковки (fMP4 мастер) × ~1.1 audio-накладной расход
= ~6.6 копий одного и того же контента на диске на тайтл.

90-минутный 1080p-фильм ≈ 3.4 GB «по проводу».
Storage на тайтл ≈ 22.4 GB.
1 000 тайтлов ≈ 22.4 TB ≈ $515 в месяц (S3 Standard).

5-кратная экономия по строке storage. Для каталога в 10 000 тайтлов это $20 000+ в месяц. Для каталога в 100 000 тайтлов (крупная стриминговая платформа) – несколько годовых зарплат инженеров.

Размен не бесплатен. CPU, который раньше отрабатывал один раз на ингесте, теперь работает на каждый запрос – или, в идеале, на каждый cache miss. Следующие разделы показывают, как этот размен по факту настраивается.

Что реально работает в момент запроса

Чтобы понять стоимость CPU JIT origin'а, надо знать, что он делает на каждый запрос. Работа – это упаковка, не энкодинг, и разница принципиальна. JIT origin не перекодирует видео. Не пережимает, не меняет кодек, не запускает x264. Кадры на диске – это те же самые кадры, что уходят «по проводу». То, что делает origin, это репакетирование: он читает кодированные сэмплы из мастер-файла fMP4 и переписывает окружающие контейнерные боксы под протокол, который попросил плеер.

Конкретно, для одного HLS-сегментного запроса JIT origin делает следующее:

  1. Парсит URL, чтобы узнать, какой тайтл, какая ступень, какой номер сегмента запрашивают.
  2. Открывает мастер-fMP4 для этой ступени.
  3. Читает бокс sidx (segment index), чтобы найти байтовый диапазон, в котором лежит сегмент 42.
  4. Читает эти байты с диска (или из кеша в памяти на «горячем» тайтле).
  5. Строит новую структуру styp (segment type), sidx, moof (movie fragment header) и mdat (media data), соответствующую HLS-разновидности fMP4, которую ждёт плеер.
  6. Если сегмент зашифрован – применяет схему CENC cbcs AES-CBC pattern к содержимому mdat правильным content key из системы управления ключами.
  7. Пишет собранные байты сегмента в тело HTTP-ответа.

На запрос манифеста JIT origin читает тот же индекс sidx, кодек-конфиг из бокса moov и длительность каждого фрагмента – и формирует свежий плейлист или MPD. Он также применяет любые манифест-фильтры, которые несёт URL (min_video_bitrate, whitelist языков аудио, whitelist DRM-систем для устройства), и включает только те ступени и дорожки, которые проходят фильтр.

Работа маленькая по сравнению с энкодингом – упаковка дешевле энкодинга примерно в 20–200 раз на секунду медиа, – но не бесплатная. Pre-packaged сегмент стоит origin'у одного read() и одного sendfile(). JIT-сегмент стоит нескольких read(), парсинга бинарных боксов, выделения свежего буфера сегмента, опционального AES-CBC шифрования каждого макроблока и HTTP-обрамления ответа. На современном железе один инстанс Unified Origin отдаёт грубо 500–2 000 JIT-сегментных запросов в секунду на ядро в зависимости от длины сегмента и наличия DRM в пути. Pre-packaged статический файловый сервер отдаёт десятки тысяч на ядро. Множитель достаточно большой, чтобы JIT origin'ы проектировались как cache-friendly первым делом – каждый JIT-запрос, который вы отдаёте, это cache miss, который вы не смогли поглотить.

Почему нужен shield

Самое важное архитектурное правило JIT origin'а: поставьте перед ним origin shield. Без него JIT не работает экономически на масштабе. Origin shield – это выделенный одноуровневый кеш CDN, который сидит между остальными edge-узлами CDN и JIT origin'ом. Любой cache miss на любом edge-узле в мире сначала идёт в shield; только cache miss на shield доходит до origin'а. CloudFront, Akamai, Fastly и CloudFlare продают origin-shield в линейке. (Подробнее – Origin shielding и многоуровневое кеширование.)

Почему shield критичен именно для JIT: типичный глобальный CDN имеет десятки–сотни edge-узлов, у каждого свой кеш. Без shield первый зритель в Токио, первый в Франкфурте, первый в Сан-Паулу и первый в Мумбае независимо триггерят cache miss до JIT origin'а – за одним и тем же сегментом. Origin упакует одни и те же байты четыре раза. С shield только первый cache miss в мире доходит до origin'а; все региональные edge'ы наполняются из shield, не из origin'а.

Опубликованные цифры большие. AWS в докладах re:Invent про MediaPackage называет сокращение egress-трафика origin'а около 95% на типичных OTT-нагрузках. Cloudflare и Akamai называют схожие диапазоны. Импликация для JIT: с shield'ом нагрузка на origin падает примерно в 20 раз по сравнению с прямым трафиком edge → origin. Без shield JIT выглядит в двадцать раз дороже в compute, чем должен быть.

Shield-у нужно ещё несколько вещей, чтобы он правильно работал именно с JIT.

  • Cache key должен включать query-параметры manifest filter. Семейство aws.manifestfilter от AWS MediaPackage, параметр ?filter= у Unified Origin – они меняют содержимое манифеста, который отдаёт origin, поэтому должны быть частью cache key. Иначе фильтрованный манифест зрителя A уйдёт зрителю B, и в плеере окажутся не те ступени. Документация MediaPackage и Unified Origin перечисляет точный список параметров, которые обязаны быть в key.
  • Cache TTL у сегментов и манифестов разные. Сегменты после публикации неизменны – сегмент 5.8 тайтла VOD никогда не меняется, – поэтому TTL в 24 часа и больше на shield нормальны. Манифесты, особенно live-манифесты, меняются каждый segment duration – 2–6 секунд, – поэтому TTL на манифесты на shield должен быть короткий: обычно 1–2 секунды для live и 60+ секунд для VOD.
  • Shield – это часть геометрии, не настроечная ручка. Команда, которая включает JIT без origin shield, видит счёт и выключает обратно, неправильно ставит диагноз. JIT без shield – сломан. JIT с shield – один из самых дешёвых способов обслуживать большой каталог.

Эталонные JIT origin'ы 2026 года

Три софта занимают почти все продакшен-деплои JIT-origin'ов в 2026 году.

Unified Origin от CodeShop (нидерландская Unified Streaming). Первый коммерческий JIT origin, поставляется с 2010 года. Работает как модуль Apache (mod_smooth_streaming плюс расширения) внутри контейнера Apache HTTP Server. Принимает один ISMV / fMP4 / MP4 источник на каждую ступень, плюс маленький XML-дескриптор (.ism), который перечисляет, какие аудио- и видео-дорожки принадлежат друг другу, – и упаковывает на лету в HLS (TS и fMP4), MPEG-DASH (включая профили DVB-DASH и HbbTV), Smooth Streaming и HDS. Поддерживает CMAF-выход со всеми тремя крупными DRM (Widevine, PlayReady, FairPlay) под схемой Common Encryption cbcs. Используется BBC Video Factory для iPlayer-каталога, Sky и десятками европейских вещателей. Модель лицензирования – per-CPU-core, что дорого на сверхмасштабе, но очень предсказуемо для средних платформ.

AWS Elemental MediaPackage, особенно поколение v2 API. Полностью managed JIT origin внутри AWS. Принимает CMAF-совместимый HLS или DASH от энкодера (обычно AWS Elemental MediaLive), хранит одну каноническую копию в S3 и упаковывает по запросу в HLS, LL-HLS, DASH и Microsoft Smooth Streaming с FairPlay, Widevine и PlayReady. Поколение v2, представленное в 2023 году и ставшее продакшен-дефолтом к 2026, добавляет origin endpoints с до 25 прикреплённых манифестов на каждый, встроенный origin shield, manifest filtering через query-параметры aws.manifestfilter и плотную интеграцию с CloudFront. Модель цен – за ингестированный GB плюс за упакованный GB egress (отдельно от лицензии per-core у Unified). «v2»-ребрендинг в консоли AWS – причина, по которой в документации 2026 года вы будете видеть и MediaPackage, и MediaPackage v2; новые сборки идут на v2, если нет конкретных причин не идти.

Eyevinn Open Source Cloud Smoothly Origin и нижележащий Eyevinn Channel Engine, плюс меньший open-source Norsk (id3as) и длинный хвост in-house origin'ов поверх Shaka Packager в library-режиме плюс своя HTTP-обёртка. Это выбор для платформ, которым нужен полный контроль над логикой упаковки – обычно из-за необычных DRM-требований, экзотических кодеков (AV1, VVC) или желания обойти и per-core-лицензию Unified, и lock-in AWS. Бессерверный паттерн Eyevinn, описанный в их постах про AWS Fargate с 2022 года, – это каноническая «JIT origin на скромном бюджете» архитектура для средних платформ.

Краткое сравнение.

OriginТипМодель лицензииManifest filteringНужен shieldТипичная нагрузка
Unified OriginКоммерческийPer-CPU-coreДа (?filter=)Да (внешний)Вещатели, крупные OTT
AWS MediaPackage v2ManagedIngested + egress GBДа (aws.manifestfilter)ВстроенныйOTT в AWS-стеке, live-спорт
Eyevinn Smoothly + Shaka libOSSНет (self-host)КастомныйДа (внешний)Средние OTT, dev-команды
NorskКоммерческий / OSS-гибридPer-channelДаДа (внешний)Live-вещатели, e-learning

Введение в инструменты упаковки, питающие любой из этих origin'ов, – в статье Упаковка видео: подробный разбор. Форматы манифестов, которые они выдают – в HLS: подробный разбор и MPEG-DASH: подробный разбор. Схема шифрования, которую они применяют – в Common Encryption (CENC).

Размен storage против compute, в цифрах

Решение между pre-packaged и JIT сводится к одному вопросу: где окажется сэкономленный на storage доллар – у вас в кармане или в счёте за compute origin'а? Арифметика ниже исходит из среднего каталога и прайс-листа AWS 2026 года без скидок по committed-spend.

Каталог в 1 000 тайтлов, средняя длина 90 минут, лесенка из 6 ступеней, две дорожки аудио, HLS + DASH.

Pre-packaged storage = ~33.6 копий × 3.4 GB ≈ 114 GB на тайтл × 1 000 = 114 TB.
Storage в месяц (S3 Standard $0.023/GB-месяц) = $2 622.

JIT storage = ~6.6 копий × 3.4 GB ≈ 22.4 GB на тайтл × 1 000 = 22.4 TB.
Storage в месяц (S3 Standard $0.023/GB-месяц) = $515.

Экономия storage = $2 107 в месяц, или ~$25 000 в год.

Сторона CPU origin'а зависит от того, сколько viewer-часов в месяц долетает до origin'а. Возьмём скромный масштаб: 1 000 000 viewer-часов в месяц, средний битрейт 4 Mbps, средняя длина сегмента 4 секунды. Это примерно 900 сегментных запросов на viewer-час, то есть 900 миллионов сегментных запросов в месяц – но почти ни один из них не доходит до JIT origin'а, если архитектура правильная.

Всего сегментных запросов в месяц       = 900 000 000
Cache hit rate на edge'ах CDN           = ~97% (типичный OTT-микс)
Miss'ов до origin shield                = ~27 000 000
Shield hit rate                         = ~95%
Miss'ов до JIT origin'а                 = ~1 350 000 в месяц

Запросов в секунду к JIT origin'у       ≈ 0.5 в среднем, 5–10 в пик
Нужно ядер JIT (1k req/s/core)          = 1 в среднем, 2 в пике

Compute origin'а (1 c6i.large EC2, $0.085/час)
                                        = $62 в месяц

Цифры иллюстративные – фактический cache hit rate, фактическое покрытие shield и профиль трафика сдвинут каждую строку на ±2× – но важна форма. Сэкономлено storage: $2 107. Добавлено compute: $62. JIT выигрывает примерно в 30× на среднем каталоге с типичным OTT-кеш-профилем.

Точка безубыточности смещается по двум переменным. Первая – размер каталога: каталог из 100 тайтлов экономит $200 в месяц на storage – недостаточно, чтобы оправдать операционную сложность, поэтому маленькие каталоги остаются pre-packaged. Вторая – cache hit rate: каталог с тяжёлым long tail и плохой cache locality (каждый тайтл смотрят раз-два в месяц) роняет shield hit rate до 60–70%, умножая compute origin'а в 5–10 раз. JIT всё равно выигрывает, но запас сокращается. Чистый long-tail архив – миллионы тайтлов, десятки viewer-часов на тайтл в месяц, мало хитов – это единственная нагрузка, где JIT окупается чисто на storage и где cache-экономика более-менее нейтральна.

Подробная пер-стек модель – в кросс-калькуляторе CDN cost economics: 95-й перцентиль, commit, overage; полная unit-экономика стриминга – в Экономика стриминга: рабочая модель.

Cache-friendliness – не опция

Репутация JIT origin'а растёт или падает на одной метрике: какую долю сегментных запросов поглощает CDN-кеш. Всё остальное – экономия storage, операционная гибкость, возможность накатить новый протокол в следующем квартале – держится на допущении, что кеш-слой несёт 95+% трафика. Когда кеш-слой не вытягивает эту цифру, JIT выглядит дорого, команда винит origin – и хорошая архитектура выкидывается.

Три вещи ломают cache-friendliness у JIT origin'ов, и все три встречаются часто.

Шум в query string. Если два плеера запрашивают один и тот же URL сегмента с разными ?session_id=, а CDN включает query string в cache key, сегмент достанется с origin'а дважды за один и тот же контент на диске. Лечится: на edge стрипать query string для сегментных URL или whitelist'ить только те параметры, которые меняют ответ (версия DRM-ключа, manifest filter), и явно исключать session- и аналитические токены. Фича Cache Policy у AWS CloudFront существует ровно ради этого; правила Cache Key у Akamai делают то же самое.

Фрагментация манифеста. Если JIT origin выдаёт чуть разный манифест на каждый user-agent – например, один для Safari, один для Chrome, один для варианта Android TV, – кеш манифестов фрагментируется по user-agent, и каждый пер-UA-манифест протягивает за собой свои сегменты. Лечится: держать манифест UA-agnostic, выпихивать device-специфичную логику в плеер (он знает, что умеет декодировать), и пусть origin выдаёт один манифест на контент.

Микроскопические TTL. Команда, которая «на всякий случай» ставит TTL манифеста VOD в 1 секунду, отдаёт 99% хитов на манифест-слое. VOD-манифесты не меняются. Они должны кешироваться столько, сколько каталог держит тайтл, – часы или дни. Только live-манифестам нужен короткий TTL, и он должен равняться длине сегмента, а не быть случайно поставленным в 1 секунду.

Cache-friendliness аудит для JIT-деплоя короткий. (1) На репрезентативном URL сегмента – даёт ли CDN cache HIT на второй запрос из другого региона? (2) Hit rate origin shield в steady-state выше 95%? (3) Не вычисляются ли одни и те же URL сегментов дважды из-за фрагментации query string? Три проверки. Они отличают JIT origin, который окупается, от того, который нет.

Типичная ошибка: воспринимать JIT как drop-in замену

Самый дорогой failure mode у команды, переходящей на JIT, – воспринимать его как drop-in замену статического origin'а, поменять NGINX на Unified Origin за тем же CDN и ждать, что счёт упадёт.

Не упадёт. Без origin shield, без настроенного cache key, без UA-agnostic манифестов JIT даст сопоставимый или больший месячный счёт, чем pre-packaged origin, который он заменил, потому что каждый cache miss теперь тратит CPU origin'а, а не просто bandwidth. Команда делает вывод: «JIT нам не подходит», откатывается – и пропускает настоящую архитектуру.

JIT – это не один продукт. Это форма – JIT origin за настроенным shield, за настроенным CDN, за UA-agnostic манифестами – и именно форма экономит деньги. Принять origin без принятия формы – это ошибка.

Лечится чек-листом, который надо пройти до выкатывания миграции в продакшен. Origin shield включён? Cache key исключает session-токены? Сегменты кешируются на edge как минимум 24 часа? Манифесты кешируются на edge segment duration (live) или часы (VOD)? Параметры manifest filter – в cache key? Каждая строка в чек-листе значима; пропуск любой из них и есть анекдот «JIT дороже».

Когда pre-packaged всё ещё выигрывает

Есть нагрузки, где pre-packaging – это правильный выбор в 2026 году.

Маленький статический каталог – корпоративная обучающая библиотека из 50 тайтлов, документальная коллекция, фиксированный набор записанных событий. Экономия storage от JIT маленькая ($100 в месяц и меньше), операционная простота файлового origin'а высокая, и инженерная стоимость поднять и настроить JIT origin перевешивает экономию.

Pass-through low-latency live – один live-канал, где энкодер пишет HLS и DASH прямо в S3-бакет, бакет является origin'ом, а возраст сегмента на edge измеряется в секундах. JIT добавляет буферизующий слой, который стоит end-to-end-латентности; для спорт-фидов на sub-2 секунды этот бюджет латентности дорог. (Арифметика латентности – в LL-HLS: подробный разбор.)

Экстремально cache-горячий каталог – вирусный одиночный ассет, крупное событие-запуск, – где 99.99% трафика идёт с крошечного числа закешированных объектов. Pre-packaging проще, а стоимость storage пренебрежимо мала, потому что каталог маленький.

Паттерн: pre-packaging выигрывает, когда каталог маленький, когда латентность священна или когда cache hit rate настолько высок, что архитектура почти ничего не решает. JIT выигрывает везде остальное.

Дерево решений: какая форма origin для какой нагрузки

Практический flow.

Рис. 2. Выбирайте pre-packaged, когда каталог маленький, бюджет латентности тугой или набор протоколов фиксирован. Выбирайте JIT – всегда за origin shield – когда каталог переваливает за пару сотен тайтлов или когда ожидается рост разнообразия протоколов.

Пороги в дереве – приблизительные: 500 тайтлов на разделение по размеру каталога, 1 секунда glass-to-glass на разделение по латентности, три протокола на разделение по разнообразию. Это не чёткие линии – это полосы. Каталог из 400 тайтлов с высоким разнообразием протоколов – это JIT-кейс. Каталог из 600 тайтлов, который отгружает только HLS в iOS-приложение, – всё ещё pre-packaged-кейс. Используйте дерево как стартовую точку и стресс-тестируйте против реальной модели стоимости.

Стратегическая ценность: новый протокол во вторник

Финансовый аргумент за JIT – арифметика storage против CPU выше – это тот аргумент, который продакт-менеджеры понимают первым, и его одного достаточно. Есть второй, плохо ложащийся в Excel, аргумент, который инженеры ценят не меньше: JIT позволяет накатить новый протокол без перепаковки каталога.

Подумайте, что происходит, когда Apple выпускает новый вариант HLS, когда у CMAF появляется новая разновидность, когда регулятор требует ротации DRM на тысячу тайтлов, когда новое семейство устройств требует подкрутки манифеста. В pre-packaged-мире каждое из этих событий – это работа по перепаковке: прочитать каждую mezzanine со storage, прогнать новые настройки упаковки, записать каждый сегмент обратно, инвалидировать CDN. Для 10 000 тайтлов это дни compute и логистический клубок.

В JIT-мире то же изменение – это deploy. Обновили логику упаковки в origin'е; следующий запрос манифеста возвращает новую форму. Mezzanine на диске не двинулись. CDN наполняется по мере прихода зрителей. Полный downtime – это столько, сколько займёт раскатка фронта origin'ов: минуты, не дни.

Причина, по которой каждая крупная OTT-платформа сошлась к JIT между 2018 и 2024 годами, – отчасти экономия storage, отчасти именно вот это: в мире, где ландшафт стриминговых протоколов меняется быстрее каталогов, каталог должен лежать в форме, которая переживёт смену протоколов. JIT даёт эту форму.

Где здесь Фора Софт

Фора Софт строит видео-пайплайны с 2005 года, включая OTT- и Internet TV-платформы, e-learning-каталоги, surveillance-архивы и telemedicine-записи, где работают те же архитектурные решения: насколько большой каталог, сколько протоколов и DRM-систем он должен обслуживать, какой бюджет латентности можно отдать на edge и где экономия storage перевешивает compute origin'а. Со стороны OTT мы строили и pre-packaged origin'ы для туго очерченных архивов событий, и JIT origin'ы (с origin shield, cache key с учётом manifest filter и настроенными CDN-политиками) для каталогов, дорастающих до тысяч. В e-learning JIT окупается в тот момент, когда библиотека курсов переваливает за пару сотен уроков. Если ваша платформа в той полосе, где решение неочевидно, архитектурный ревью короткий, конкретный и опирается на ту же арифметику выше – и обычно экономит деньги на первой миграции.

Ключевые выводы

  • Pre-packaging пишет на диск каждый пер-протокольный вариант один раз; JIT держит один мастер и синтезирует виды по запросу.
  • Экономия storage у JIT обычно идёт 3–5×, против 5–20× роста compute-нагрузки на origin.
  • Origin shield для JIT обязателен – без него compute-сторона выглядит куда хуже, чем должна.
  • Параметры manifest filter должны быть в cache key; session-токены – нет.
  • Pre-packaging всё ещё выигрывает на маленьких каталогах, sub-2 секундной live-латентности и экстремально cache-горячих одиночных ассетах.
  • Стратегическая ценность JIT помимо стоимости: новый протокол или ротация DRM раскатывается deploy'ем, не перепаковкой.

Что почитать дальше

CTA

  • Поговорить со стриминговым инженером – забронируйте 30-минутный архитектурный ревью текущего стека упаковки.
  • Посмотреть наши кейсы – OTT, e-learning и broadcast-деплои, где JIT origin или статический origin оказались правильным выбором.
  • Скачать decision sheet «JIT против pre-packaged» – одностраничный справочник: пороги каталога, арифметика storage, чек-лист cache-friendliness и вендоры origin'ов 2026 года. Скачать PDF

Строите такую систему?

Подберём параметры кодирования под ваш контент и посчитаем стоимость доставки до старта разработки.