Инвалидация кэша в стриминге: редко используют, часто неправильно

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

TL;DR

Инвалидация кэша – это команда CDN забыть сохранённую копию объекта, чтобы следующий запрос пришёл за свежей версией к origin. В стриминге это почти бесполезный инструмент для задач, к которым часто прибегают неопытные команды: деплоев, изменений плейлиста, обновлений лестницы, исправлений багов. Эти задачи решаются тремя другими подходами – коротким Cache-Control на манифестах, длинным Cache-Control в сочетании с версионированными именами файлов для сегментов и переписыванием segment timeline прямо в манифесте. Инвалидация остаётся актуальной только для случаев, которые эти подходы не покрывают: ротация ключей DRM, удаление по DMCA или GDPR, редакционное снятие контента или критический баг в фрагменте, который нельзя ждать три часа до истечения TTL.

Зачем это нужно

Если у вас стриминговый продукт на CDN, рано или поздно кто-нибудь в команде предложит «давайте просто очистим кэш» как фикс проблемы. Симптом они опишут правильно – пользователи видят старый контент. Инструмент почти всегда будет выбран неправильно. Массовая инвалидация в большинстве CDN медленная, платная сверх небольшого фритира и тихо разрушает cache hit ratio, на котором держится ваш бюджет. Эта статья – для инженера, которому дали кнопку purge, тимлида, желающего понять, когда это реально правильный ответ, и продакта, которому нужен короткий чек-лист до того, как прилетит очередной «срочный takedown».

Что такое «инвалидация кэша» на самом деле

CDN хранит копии ваших файлов на edge – рядом со зрителем – чтобы отвечать на запросы, не обращаясь к origin. Инвалидация – это команда CDN: «забыть» свою копию этого файла; следующий, кто его запросит, получит свежие данные с origin. Большинство CDN (Cloudflare, Fastly, Akamai, Google Cloud CDN) называют эту операцию purge; Amazon CloudFront использует термин invalidation. По сути – это одно и то же.

Три детали в этом простом определении регулярно подводят команды.

Во-первых, инвалидация не моментальна. CloudFront документирует 5–25 секунд для своих новых cache tag инвалидаций (P95) и 10–15 минут для классических path-инвалидаций – это время распространения по всем edge. Fastly известен скоростью: его purge-all завершается глобально за ~150 миллисекунд. Но для лайв-сегментов, которые уже покинули кэш и лежат в буфере плеера, даже 150 мс – поздно.

Во-вторых, инвалидация на уровне масштаба платная. Первые 1 000 путей инвалидации в месяц в CloudFront предоставляются бесплатно; всё, что сверх нормы, – по $0,005 за путь. Wildcard-путь (/season-3/*) считается одним путём, даже если он соответствует ста тысячам объектов, поэтому «инвалидация префикса» почти всегда дешевле, чем «инвалидация каждого сегмента». Akamai и Cloudflare публикуют корпоративные лимиты, превышение которых приводит к throttling.

В-третьих, инвалидированный объект не удаляется из origin. Инвалидация очищает только кэш CDN. Если повреждённая версия файла всё ещё находится на origin, следующий запрос после инвалидации снова загрузит ту же плохую версию в кэш – и тогда инвалидация окажется напрасной. Правильный порядок всегда один: сначала исправьте origin, потом выполняйте инвалидацию.

Рис. 1. Что делает инвалидация на самом деле – и чего она не делает.

Почему «purge URL» – неверный ход в стриминговом пайплайне

Команды статических сайтов по умолчанию используют purge, потому что их модель контента это поощряет. Пост в блоге обновляется – вы очищаете URL – и мир видит свежую версию через несколько секунд. Эта привычка плохо работает в стриминге, потому что стрим – это не один URL, а динамическое дерево URL, структура которого меняется каждую секунду.

Типичный live HLS-стрим включает master-плейлист, четыре–шесть media-плейлистов (по одному на уровень bitrate ladder), один init-сегмент на рендеринг, ключевой URI и хвост media-сегментов, который packager добавляет и удаляет каждые несколько секунд. Один зритель на интервале 4-секундных сегментов запрашивает около 30 различных URL в минуту. Событие с десятью тысячами зрителей поддерживает сотни тысяч объектов в кэше в любой момент времени.

Если у вас рефлекс «стрим сломан – purge», вас ждут несколько неприятных фактов. Вы не можете очистить сегменты, уже попавшие в буферы плееров – они покинули CDN и хранятся на устройстве зрителя. Скорее всего, вы не успеете выполнить purge быстрее, чем packager генерирует новые сегменты: при двухсекундных сегментах к моменту глобального purge уже появятся три новых сегмента, которые вы не очистите. А массовый purge live-origin – одна из немногих операций, способная сама по себе сломать стрим: все плееры одновременно начнут revalidation, и пул соединений с origin просто схлопнется.

Для статических VOD-ассетов математика проще, но логика остаётся ошибочной. Правильный вопрос почти никогда не звучит как «как мне сделать purge?». Он должен быть таким: «почему я оказался в ситуации, где purge необходим?». В здоровом пайплайне на этот вопрос мало ответов, и четыре других инструмента эффективнее и дешевле решают каждый из них.

Четыре инструмента, заменяющие инвалидацию в стриминге

Считайте инвалидацию четвёртым вариантом в этом списке, а не первым. Первые три покрывают около 95% всей работы.

Инструмент 1 – короткий Cache-Control для изменяющихся ресурсов

Манифесты в live-стриме постоянно обновляются, поэтому их нужно кэшировать на edge-сервере как можно короче – чтобы плеер, запрашивающий актуальный плейлист, действительно получил свежий. Распространённое правило – половина target segment duration: стрим с целевой длительностью сегмента 6 секунд должен кэшировать max-age манифеста в течение 3 секунд; стрим с сегментами по 2 секунды – 1 секунды. Apple HLS Authoring Specification формулирует ту же идею через привязку свежести плейлиста к моменту появления следующего сегмента.

Для media-сегментов – которые не изменяются после создания – ситуация иная: Cache-Control: public, max-age=31536000, immutable. Директива immutable (определена в RFC 8246) указывает браузерам и CDN, что можно пропускать даже недорогую проверку актуальности (revalidation round-trip). Комбинация «манифест, обновляющийся каждую секунду» и «immutable-сегмент, действующий год» – фундамент любой правильно настроенной стриминговой конфигурации CDN.

Инструмент 2 – версионированные имена файлов

Если сегменту действительно нужно изменить – обычно потому, что вы его перекодировали, починили вставку рекламы или убрали заикание – просто поменяйте ему имя. Объект season-3/episode-7/v1/segment-00042.m4s становится season-3/episode-7/v2/segment-00042.m4s. Манифест теперь указывает на путь v2; CDN видит URL, который никогда не кэшировал; origin отдаёт свежие байты; URL v1 сам выходит из кэша по TTL.

Именно этот паттерн позволяет безопасно ставить на сегменты max-age=31536000. Никакой необходимости инвалидировать сегмент нет, если его имя меняется каждый раз при изменении байтов. Документация CloudFront прямо называет такой подход «first-class». Bitmovin, Mux и AWS Elemental MediaPackage по умолчанию используют версионированные пути именно по этой причине.

Математика такова: CDN, отдающий версионированные сегменты при коэффициенте попадания в кэш 99%, обходится примерно в 1% от стоимости аналогичной нагрузки без версионирования – ведь редкие промахи происходят только тогда, когда зритель впервые запрашивает абсолютно новый URL. Команда, выполняющая очистку кэша при каждом деплое, платит эту разницу каждый раз.

Инструмент 3 – переписывание временной шкалы сегмента

Для live-стримов сам манифест выступает в роли примитивного механизма инвалидации. Packager удаляет сегмент из окна медиаплейлиста (HLS) или из элемента SegmentTimeline (DASH) – и плееры перестают запрашивать его при следующем обновлении плейлиста. DASH-IF Implementation Guidelines прямо описывают это: «последний период может перейти от неограниченной длительности к фиксированной… или один или несколько периодов могут быть полностью удалены с конца временной шкалы MPD». HLS использует EXT-X-MEDIA-SEQUENCE и скользящее окно записей EXTINF с аналогичным эффектом.

Для зрителя это незаметно. Плохой контент исчезает из плейлиста; плееры обновляют его в пределах окна target-duration; через несколько секунд каждый новый зритель уже не помнит о сегменте. Устаревшая копия сегмента в кэше CDN не имеет значения – её никто не запрашивает.

Паттерн работает в live-стриме ровно по той причине, по которой не работает в VOD: live-манифест динамичен, а VOD-манифест – статичен. Для VOD остаются только два варианта – инструмент 2 (версионирование) или инструмент 4 (настоящая инвалидация).

Инструмент 4 – реальная инвалидация кэша, но только если первые три не помогают

Когда вы применили инструменты 1–3, а некачественный контент всё ещё попадает к зрителям – инвалидация становится правильным решением. Подходящие сценарии довольно узки. Перечислим их ниже.

Рис. 2. Дерево решений, которое должно висеть в комнате до того, как кто-то нажмёт purge.

Когда инвалидация – правильный инструмент

Четыре сценария из реальной практики стриминга.

Ротация ключа DRM на лету

Common Encryption (CENC, ISO/IEC 23001-7) и модель лицензий EME поддерживают ротацию ключей для непрерывного live-стрима: ключ шифрования периодически обновляется, сегменты после точки ротации шифруются новым ключом, а плееры заранее получают новую лицензию. Если ротация происходит раньше запланированного – например, из-за отзыва прав у подписчика – может потребоваться инвалидировать кэшированный ответ по URI ключа, чтобы следующий запрос привёл к получению актуальной лицензии. Самим сегментам инвалидизация не нужна – инвалидировать следует только ключ.

Операция точечная и хирургическая: purge затрагивает только пути под EXT-X-KEY (HLS) или ContentProtection URL (DASH). Больше ничего. За считанные секунды отключите отозванного зрителя на следующем интервале запроса ключа, не затрагивая стрим для остальных.

Takedown по DMCA, GDPR или «праву на забвение»

Если третья сторона направила DMCA-уведомление на фрагмент VOD, требование safe-harbour предполагает удаление «expeditiously» – обычно в течение 24 часов. Аналогичная срочность действует и для запросов на удаление по GDPR, а также для контрактных takedown (например, спортивная лига удаляет хайлайты из-за регионального блэкаута).

Процедура: сначала убрать ассет с origin, затем инвалидировать wildcard-префикс на CDN, после чего оставить ответ 410 Gone или 451 Unavailable на origin – на случай, если кто-то обратится к кэшированному URL в период распространения. Версионирование здесь не поможет – плохая версия была единственной, и «забыть v1» – это требование целиком.

Развёрнутый баг в одном куске контента

Вы выпустили новую перекодировку 90-минутного фильма. QA сообщает, что аудио сдвинуто на два кадра – но только в рендере 720p. Перекодирование занимает час. Ждать час с битым файлом перед 50 000 зрителей вы не можете.

Прагматичный ход: перекодировать в новый версионированный путь (инструмент 2), обновить манифест на новый путь и отменить валидность только манифеста, чтобы кэшированная копия master-плейлиста на CDN обновилась мгновенно. Битые сегменты сами выйдут из кэша по TTL. Вы тратите одну инвалидацию вместо 800.

Live-стрим, который реально пошёл не так

Ведущий сказал то, что юристы не могут оставить в эфире. Нужно сократить окно прямого эфира и удалить запись VOD до её публикации. Live: остановить приём потока, дать сегментам автоматически удалиться из таймлайна. VOD: убрать ассеты с origin, аннулировать wildcard на CDN, опубликовать чистую версию по новой ссылке.

Это канонический случай, когда любой другой инструмент оказывается слишком медленным: playlist roll-off закрывает live, wildcard-инвалидация – VOD, версионирование – замену.

Как крупные CDN реализуют инвалидацию в 2026

Одна и та же операция описывается шестью разными словарями. Ниже приведена таблица – именно то, что каждая команда хотела бы иметь под рукой в первый день.

CDNНазвание операцииPath scopeTag / surrogate-keyВремя распространенияЦены
Amazon CloudFrontInvalidationPath + wildcard (/path/*)Cache Tag (апрель 2026) через response header10–15 мин (path); < 5 с P95 (tag)Первые 1 000 paths/мес бесплатно; $0.005 каждый сверх
Akamai (CDN / Adaptive Media Delivery)Fast PurgeURL, CP code, ARLEdge-Cache-Tag header~5 секундВключено в commit; rate-limited
CloudflarePurgeURL, prefix, hostname, всёCache-Tag header (Enterprise)< 30 секунд глобальноВключено в план; квоты на зону
FastlyPurgeURL или Surrogate-KeySurrogate-Key (бесплатно, все тарифы)~150 мс (instant purge)Включено в usage; batch API для ключей
Google Cloud CDN / Media CDNInvalidatePath + wildcardCache tag (response header)Несколько минутПервые записи бесплатно в месяц; usage сверх
Edgio (Verizon Digital Media)PurgeURL, list, dirSurrogate keysНесколько секундВключено; отдельные endpoint для live и VOD

Три нюанса стоит выделить.

Операция cache tag – то, что изменило этот рынок. Fastly внедрил surrogate keys в 2014 году и десять лет сохранял преимущество для стриминговых команд, которым нужно было группировать тысячи сегментов под одним тегом и очищать всю группу одним запросом. Akamai и Cloudflare последовали за ним. CloudFront добавил инвалидацию по Cache Tag в апреле 2026 года – задержка P95 составила пять секунд, через response-заголовок, по той же модели, что и у Fastly. Стриминговые нагрузки на AWS, ранее ограниченные инвалидацией по пути, получили более изящный инструмент.

Время распространения – это best-case, а не worst-case. Указанные CloudFront цифры в 10–15 минут для инвалидации по пути – документированное поведение; обращения в поддержку AWS показывают более длинные хвосты у дистрибутивов с большим количеством edge-узлов. 150 мс у Fastly – реальная цифра, но она относится только к узлам, которые уже получили команду purge: узел, только что подключённый к POP, может отдавать устаревший контент дольше. Планируйте так, будто хвост задержки в два–три раза превышает документированный.

Вас могут ограничить по скорости (rate-limit). CloudFront применяет троттлинг при слишком большом количестве инвалидаций в процессе выполнения (ошибка TooManyInvalidationsInProgress). Akamai и Cloudflare устанавливают лимиты на количество операций очистки в минуту на аккаунт. Команда, которая автоматизирует «очистку после каждого деплоя», рано или поздно столкнётся с проблемой во время реального инцидента.

Две ловушки, которые тихо ломают продукт

«Ловушка – сначала origin, потом инвалидация. Инвалидация при всё ещё неработающем origin вернёт плохой контент обратно в кэш, и усилия окажутся напрасными. Правильный порядок: сначала остановить отдачу повреждённого файла с origin, потом проводить инвалидацию. В случае takedown это означает сначала удалить ассет (или вернуть 410).»
«Ловушка – расползание scope wildcard. Инвалидация /series-7/* выглядит узко; инвалидация /*, нацеленная на одну опечатку, сводит к нулю глобальный cache hit ratio всех остальных ассетов дистрибутива на ближайшие полчаса. Рекомендация CloudFront: «указывайте path только к тем файлам, которые действительно нужно инвалидировать». Поставьте guardrail в деплой-пайплайн, который отклоняет любой path с более чем одним замыкающим wildcard.»

Третью стоит упомянуть одной строкой – она встречается реже: инвалидация по URL с параметрами подписи может не сработать, если ключ кэша включает подпись. Статья 6.3 – Cache keys for streaming подробно разбирает половину этой проблемы, касающуюся ключей кэша.

Рис. 3. Расположение каждого инструмента на плоскости «цена × латентность × точность».

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

Большинство наших клиентов в сфере стриминга, OTT, e-learning, телемедицины и видеонаблюдения сталкиваются с проблемами инвалидации в первые полгода после запуска – обычно это takedown, ротация ключей или сбой при развёртывании ladder. С самого начала мы внедряем в платформу playbook из четырёх инструментов: короткий max-age на манифестах, неизменяемые версионированные сегменты, механизм rolloff, управляемый по сегментно-временной шкале для live-трансляций, и защищённый путь инвалидации, требующий подтверждения «origin починен» и ревью wildcard scope. Та же архитектура лежит в основе нашей работы с DRM и compliance, где разница между «мы проверили всё» и «мы исправили нужное» – это разница между чистым инцидентным отчётом и шестизначным счётом от CDN.

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

  • Инвалидация медленная, дорогая и неточная – это крайняя мера, а не часть процесса деплоя.
  • Короткие TTL для манифестов, неизменяемые версионированные сегменты и отбраковка устаревших сегментов по времени покрывают около 95% задач.
  • Реальные случаи для инвалидации: ротация ключей DRM, удаление контента, ошибка в одном ассете, отзыв активного стрима.
  • CloudFront внедрил инвалидацию по cache tag в апреле 2026 года – распространение за пять секунд, в стиле surrogate keys.
  • Сначала исправляйте origin; только потом инвалидируйте; использование wildcard – только после ревью.
  • Wildcard /* почти никогда не является правильным решением; префикс /series-7/season-3/* – обычно да.

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

Призыв к действию

Поговорить со стриминговым инженером о политике инвалидации кэша для вашей платформы · Посмотреть кейсы в стриминге, OTT и телемедицине · Скачать Cache Invalidation Playbook – одностраничный чек-лист с 4 инструментами, 4 сценариями, в которых инвалидация действительно нужна, и 6 проверками, которые on-Call должен пройти перед нажатием кнопки purge.

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

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