Темы



Медиаобработка Netflix Stratum: Автоматизированный подбор оптимального размера контейнеров

Коротко сгенерировано ИИ по тексту статьи
  • Инженеры Netflix создали систему Stratum Resource Tuner для автоматического подбора оптимальных размеров контейнеров в продакшене без участия человека.
  • Оптимизация нацелена на задачи, на которые приходится 70–80% потребления мощностей среди сотен тысяч ежедневно запускаемых контейнеров.
  • Система ежедневно анализирует телеметрию за месяц, вычисляя лимиты по 99-му перцентилю для процессора и по 99,9-му с запасом для памяти.

Почему это важно: Неправильные конфигурации контейнеров повышают когнитивную нагрузку на разработчиков и увеличивают эксплуатационные расходы владельцев платформы.

Авторы: Виолетта Пидволоцкая и Навеин Маредди

Stratum — это внутренняя бессерверная платформа Netflix для обработки медиаданных, созданная на основе более чем десятилетнего опыта разработки крупномасштабных распределенных систем. Она обеспечивает выполнение широкого спектра медиазадач — включая кодирование, упаковку, инспекцию и оценку качества, — которые лежат в основе воспроизведения, рекламы, студийных рабочих процессов, векторов ИИ (эмбеддингов) и многого другого.

Инженеры разрабатывают функции Stratum, упаковывая код приложения и зависимости ОС в образы OCI. Затем Stratum планирует эти контейнеры в качестве пакетных заданий (batch jobs) на вычислительной платформе Netflix Titus, а вышестоящие сервисы инициируют запуск функций.

Каждый день Stratum управляет сотнями тысяч контейнеров в рамках пиковых, высокопроизводительных и чувствительных к задержкам рабочих нагрузок. Будучи ключевой платформой Netflix для обработки медиаданных, эта система должна масштабироваться по мере появления в каталоге новых форматов контента, таких как подкасты, прямые трансляции, спорт, реклама или региональные потоки приема, например TF1 во Франции.

Чтобы запросить ресурсы для этих функций, владельцы указывают лимиты ЦП, памяти, диска и сети в виде конфигурации YAML, как показано ниже:

functionName: VideoEncoder.encodeV1
resources:
numCpus: 8
memoryInMB: 18000
diskSizeInMB: 50000
networkInMbps: 1000

Поддержание оптимальных значений вручную — сложная задача в условиях развивающейся инфраструктуры Netflix, обновления инстансов EC2 и изменений на уровне приложений. В результате конфигурации часто создаются с избыточным запасом ресурсов или со временем незаметно отклоняются от идеальных значений. Неправильно подобранные конфигурации — это универсальная проблема крупномасштабных бессерверных платформ, которая создает дополнительную когнитивную нагрузку на разработчиков функций и увеличивает эксплуатационные расходы для владельцев платформы.

В этой статье мы рассказываем о том, как мы создали Stratum Resource Tuner (SRT) — автоматизированную систему, которая безопасно оптимизирует размеры работающих контейнеров в продакшене без вмешательства человека. Мы рассмотрим реальные примеры, нашу архитектуру безопасности и выводы, которые мы сделали, когда одно из автоматизированных изменений пошло не по плану.

Проблема: избыточное выделение ресурсов

Когда инженеры пишут новую функцию Stratum, они обычно копируют конфигурационный файл YAML из существующей функции или настраивают ее параметры под абсолютно худший сценарий. Оказавшись в продакшене, инженеры редко возвращаются к этим конфигурациям до тех пор, пока не произойдет сбой, что заставляет их перестраховываться и выделять ресурсы с избыточным запасом.

Ручная настройка ресурсов не масштабируется по следующим причинам:

  • Высокие эксплуатационные издержки: Снижение объемов ресурсов требует дней ручного мониторинга метрик и тестирования методом проб и ошибок, что отвлекает ценные инженерные ресурсы от другой высокоэффективной работы. Если сокращение окажется чрезмерным, инженеры столкнутся с инцидентами в продакшене, из-за чего ручная настройка превращается в задачу с высоким риском и низкой отдачей.
  • Непрерывная эволюция инфраструктуры и кодеков: Облачные провайдеры регулярно обновляют свое аппаратное обеспечение. Выделение ресурсов, которое было оптимальным для старого поколения оборудования, незаметно становится неэффективным на новом железе. В то же время Netflix постоянно совершенствует медиастандарты и алгоритмы кодирования (такие как AV1, AV2 и пространственный звук). Конфигурация, настроенная под один кодек, может оказаться неоптимальной при выпуске усовершенствованного алгоритма.
  • Динамическая эволюция рабочих нагрузок: По мере того как Netflix расширяет присутствие в новых медиаформатах — таких как потоковые видеоподкасты, спорт, интерактивные рекламные форматы с адаптацией под ИИ и крупные интеграции с вещательными компаниями, например TF1 во Франции, — требования к обработке медиаданных могут непредсказуемо меняться, делая статические лимиты ресурсов контейнеров неточными.
  • Рост затрат на отраслевое аппаратное обеспечение: Из-за колоссального глобального спроса на ИИ-инфраструктуру цены на серверное железо и оперативную память продолжают расти, из-за чего простаивающая память контейнеров обходится все дороже.
  • Накопительный масштаб платформы: В масштабах Netflix даже незначительное избыточное выделение ресурсов экспоненциально умножается на сотни тысяч ежедневных запусков контейнеров, аккумулируя растраченные мощности по всей платформе Stratum.

Чтобы оценить масштаб проблемы, мы проанализировали исторические данные об использовании ресурсов в рабочих нагрузках Stratum. Телеметрия подтвердила нашу гипотезу: избыточное выделение ресурсов происходило часто, потери вычислительной мощности накапливались, а устойчивый путь вперед требовал принципиального пересмотра подходов к управлению конфигурациями ресурсов.

Знакомство со Stratum Resource Tuner

Чтобы решить вышеупомянутые проблемы, мы создали Stratum Resource Tuner (SRT) для автоматического подбора оптимального размера контейнеров Stratum. Наша главная цель — сделать так, чтобы пользователям никогда не приходилось вручную указывать конфигурации ресурсов. Мы начали с небольшого набора высокопроизводительных рабочих нагрузок с мягкими требованиями к задержкам, на которые приходится большая часть (70–80%) потребления ресурсов.

В качестве краткого пояснения к терминологии: в этой статье мы используем термины «оптимизация размера» (right-sizing) и «тюнинг» (tuning) как взаимозаменяемые. Под «уменьшением» (downsizing) понимается снижение лимитов ресурсов, а под «увеличением» (upsizing) — их наращивание. Поскольку наша цель — оптимизация затрат, в этой статье основное внимание уделяется уменьшению ресурсов.

Автоматическая оптимизация размера не включена по умолчанию. Владельцы функций должны вручную активировать ее для каждого типа ресурсов (например, ЦП, памяти, сети или диска). После подключения SRT работает без участия человека в пять этапов:

Рисунок 1: Общая схема рабочего процесса SRT

  1. Сбор метрик использования ресурсов по всем выполнениям данной функции.
  2. Генерация рекомендации для каждого типа ресурсов (например, ЦП или памяти).
  3. Проверка рекомендации посредством экспериментов.
  4. Применение или отклонение рекомендации на основе результатов экспериментов.
  5. Мониторинг метрик после применения для выявления аномалий.

«Рекомендация» — это ключевая сущность в SRT и основная единица работы. По мере прохождения этапов SRT переводит рекомендацию через несколько состояний:

Рисунок 2: Автомат состояний рекомендации

  • CREATED (СОЗДАНА): запланированный рабочий процесс сгенерировал рекомендацию.
  • EVALUATING (ОЦЕНКА): выполняется проверка рекомендации, и SRT анализирует результаты.
  • APPLIED (ПРИМЕНЕНА): все эксперименты прошли успешно, и SRT автоматически применил рекомендованную конфигурацию.
  • REJECTED (ОТКЛОНЕНА): по меньшей мере один эксперимент завершился неудачно, конфигурация функции осталась без изменений.
  • MONITORED (МОНИТОРИНГ): SRT отслеживает рекомендацию в течение периода стабилизации (soak period) после применения для проверки стабильности.

В следующих разделах каждый из этих этапов рассматривается подробно. Для иллюстрации процесса мы проследим реальный жизненный цикл функции VideoEncoder.encodeV1 — высокопроизводительной функции кодирования видео, для которой были успешно оптимизированы избыточные объемы памяти и ЦП.

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

Сбор метрик

Чтобы такие рекомендации были возможны, нам необходим надежный механизм сбора метрик. Каждый контейнер Stratum сообщает метаданные выполнения своей функции, параметры инфраструктуры и утилизацию ресурсов (ЦП, память, диск и сеть) с разрешением менее минуты.

Эти метрики поступают через Keystone, платформу потоковой передачи событий Netflix в реальном времени, и попадают в два независимых хранилища данных:

Рисунок 3: Сбор метрик

  • Хранилище сводок выполнения (Execution summaries store): содержит сводные метрики на уровне выполнения, проиндексированные в Elasticsearch для быстрого точечного поиска. Оно служит нашим краткосрочным хранилищем данных для запросов и проверки отдельных запусков.
  • Долгосрочное хранилище высокого разрешения: хранит сырые метрики использования с высоким разрешением в таблицах Iceberg. Хотя выполнение запросов к нему занимает больше времени, оно служит нашим долгосрочным хранилищем, содержащим историю за месяцы для анализа трендов использования ресурсов.

Для каждого выполнения записывается одна запись, которая представляется в виде спана (span). Вот как эти записи выглядят для одного спана нашей функции VideoEncoder.encodeV1.

В Elasticsearch запись фиксирует общую сводку завершенного спана, идентифицируемую по тегу tags.stratum.spanId:

{
"tags.stratum.spanId": "38536313f65f060a",
"tags.functionName": "VideoEncoder.encodeV1",
"tags.stratum.phase": "run",
"tags.stratum.success": true,
"tags.stratum.retriedWithMoreResources": false,
"tags.stratum.function.execDurationSecs": 26,
"tags.cpuCount": 8,
"tags.memoryInMB": 18000,
"tags.diskInMB": 50000,
"tags.networkInMbps": 1000,
"tags.titusTaskId": "06e1a7c0-2502-4a54-905f-b13a1e786107",
"tags.instanceType": "r7a.24xlarge",
"tags.nf.region": "us-east-1",
"ts": 1780743028000
}

В Iceberg запись содержит те же метаданные, но дополняется временными рядами утилизации ресурсов с секундным разрешением, которые отслеживались во время этого спана:

{
"span_id": "38536313f65f060a",
"function_name": "VideoEncoder.encodeV1",
"phase": "run",
"success": true,
"start_epoch_secs": 1780743002,
"end_epoch_secs": 1780743028,
"runtime_secs": 26,
"cpu_requested": 8,
"memory_mb_requested": 18000,
"disk_mb_requested": 50000,
"network_mbps_requested": 1000,
"titusTaskId": "06e1a7c0-2502-4a54-905f-b13a1e786107",
"instance_type": "r7a.24xlarge",
"tags.stratum.retriedWithMoreResources": false,
"env": "prod",
"resource_usage": [
{ "cpu_usage": 1.13, "memory_mb": 3701.37, "disk_mb": 20120.4, "net_in_mb": 221.09, "net_out_mb": 0.12 },
{ "cpu_usage": 2.25, "memory_mb": 3584.09, "disk_mb": 25410.1, "net_in_mb": 0.02, "net_out_mb": 0.05 },
{ "cpu_usage": 4.16, "memory_mb": 6750.79, "disk_mb": 30400.5, "net_in_mb": 165.90, "net_out_mb": 0.38 },
...
]
}

Генерация рекомендаций

Запланированный рабочий процесс Conductor запускается ежедневно, считывая данные об использовании за последний месяц из Iceberg и генерируя рекомендации для каждой функции и типа ресурсов. Рабочий процесс также генерирует рекомендации для функций, которые не подключили автоматическую оптимизацию размера, чтобы оценить потенциальную экономию.

Каждая рекомендация сохраняется в хранилище рекомендаций, что позволяет нам выполнять запросы и фильтровать рекомендации по функции, типу ресурсов или статусу в оперативном режиме.

Рисунок 4: Последовательность генерации рекомендаций

Для каждой функции и типа ресурсов рабочий процесс применяет следующую логику генерации:

  • Фильтрация по типу рабочей нагрузки: мы оптимизируем только высокопроизводительные рабочие нагрузки. Это позволяет сосредоточить наши усилия на правильном подборе размеров, что дает наиболее ощутимую экономию в масштабе всего парка.
  • Агрессивная оптимизация ЦП и сети: мы ориентируемся на 99-й перцентиль (p99) использования без дополнительного запаса. ЦП и сеть — это сжимаемые ресурсы; если контейнер время от времени достигает этих лимитов, функция может выполняться чуть медленнее.
  • Консервативная оптимизация памяти и диска: мы ориентируемся на 99,9-й перцентиль (p99.9) использования и включаем буфер безопасности. Нехватка физической памяти или дискового пространства приводит к фатальным сбоям — таким как аварийное завершение по исчерпанию памяти (OOM) или диска (OOD), — поэтому защитный запас имеет решающее значение.
  • Применение средств защиты к изменениям: мы отбрасываем рекомендации, если абсолютное сокращение слишком мало, чтобы оправдать операционные усилия. Для памяти и диска мы ограничиваем максимальное сокращение, разрешенное за один цикл, на уровне 15% — это лимит безопасности, введенный после анализа первых запусков в продакшене.

Рабочий процесс создает новые рекомендации в состоянии CREATED. Если для данной функции и типа ресурсов в этом состоянии уже существует рекомендация, SRT перезаписывает ее обновленными расчетами. Как только рекомендация выходит за рамки состояния CREATED, поля recommended_value и stats становятся неизменяемыми. Последующие ежедневные запуски генерируют новую рекомендацию с уникальным идентификатором вместо изменения существующей записи.

Вот как эти рекомендации выглядят для различных типов ресурсов в своем исходном состоянии CREATED для нашей функции VideoEncoder.encodeV1:

  • Рекомендация по ЦП
{

"function_name": "VideoEncoder.encodeV1",
"env": "prod", "resource_type": "CPU",
"current_value": 8, "recommended_value": 4,
"status": "CREATED",
"resource_cost_usd_per_hour": ***,
"stats": {
"usage": { "p99": 4.16, "p999": 4.57 },
"execution": {
"total_fn_executions": 748762182,
"success_fn_executions_pct": 99.75,
"total_fn_exec_runtime_hr": 88102723
},
"window": { "start": "2026-05-05T00:00:00Z", "end": "2026-06-05T00:00:00Z" }
},
"experiment_inputs": null,
"experiment_workflow_execution_id": null,
"outcome_message": null,
"finalized_at": null
}
  • Рекомендация по памяти (сокращение на 15% за один шаг)
{
"id": "2edb734a-6184-4f5e-8ffa-23004bd665d7",
"function_name": "VideoEncoder.encodeV1",
"env": "prod", "resource_type": "MEMORY_MB",
"current_value": 18000, "recommended_value": 15300,
"status": "CREATED",
"resource_cost_usd_per_hour": ***,

"stats": {
"usage": { "avg": 5296.43, "p99": 6750.8, "p999": 7820.3 },
"execution": {
"total_fn_executions": 748762182,
"success_fn_executions_pct": 99.75,
"total_fn_exec_runtime_hr": 88102723
},
"window": { "start": "2026-05-05T00:00:00Z", "end": "2026-06-05T00:00:00Z" }
},
"experiment_inputs": null,
"experiment_workflow_execution_id": null,
"outcome_message": null,
"finalized_at": null
}

По мере прохождения рекомендацией своего жизненного цикла SRT заполняет остальные параметры.

При переходе к этапу проверки SRT переводит статус рекомендации в EVALUATING, записывает настройки целевого эксперимента и связывает активный запуск рабочего процесса, отслеживающий ход эксперимента.

Наконец, после завершения проверок статус изменяется на APPLIED или REJECTED, сохраняя детали результатов и временную метку завершения для анализа.

Повторная попытка с большим количеством ресурсов

Мы придерживаемся консервативного подхода к генерации рекомендаций, отдавая приоритет стабильности системы, а не максимальной эффективности. Поскольку рекомендации опираются на исторические данные об использовании, они не всегда могут предсказать внезапные всплески или новые профили нагрузок, когда функции сталкиваются с тяжелыми, ранее не встречавшимися запросами.

Для обработки таких неожиданных всплесков мы разработали отказоустойчивый механизм. Процесс-наблюдатель, работающий в каждом оптимизированном контейнере, отслеживает использование памяти и диска во время выполнения функции. Если контейнер превышает заранее установленные пороговые значения (85% для некэшированного использования памяти или 95% для использования диска), наблюдатель помечает выполнение как высокорисковое, отменяет его и перенаправляет задачу в очередь на более крупный контейнер:

new_container_size = original_container_size * 1.5

Этот коэффициент 1.5 применяется только к параметрам памяти и диска.

Рисунок 5: Повторная попытка с большим количеством ресурсов

Этот механизм «повторной попытки с большим количеством ресурсов» служит нашей страховочной сеткой: более крупные конфигурации контейнеров применяются только при повторном выполнении задач для самовосстановления в крайних случаях. Хотя такие редкие повторные попытки влекут за собой дополнительные вычислительные затраты и задержки, они позволяют нам поддерживать высокую степень оптимизации повседневных конфигураций без необходимости изначально резервировать ресурсы под редкие дорогостоящие пики.

Для нашей функции VideoEncoder.encodeV1, если тяжелый запуск приводит к тому, что использование памяти превышает пороговое значение 85% (15 300 МБ) в рамках текущего контейнера на 18 000 МБ, система прерывает выполнение и перезапускает его в контейнере на 27 000 МБ.

Хотя мы предпочитаем инициировать повторные попытки на основе реальных событий OOM или OOD, а не заранее заданных пороговых значений, технические ограничения нашей текущей архитектуры затрудняют надежное обнаружение самих событий. Использование заданных пороговых значений служит надежным временным решением, пока мы разрабатываем более совершенные возможности обнаружения.

SRT автоматически включает механизм повторных попыток для любой функции, для которой подключена оптимизация памяти или диска. Каждый контейнер Stratum сообщает о событиях повторных попыток, которые поступают в Elasticsearch и Iceberg наряду со стандартной телеметрией производительности.

Проверка рекомендаций

Каждая рекомендация должна пройти двухэтапный процесс проверки под управлением рабочего процесса Conductor перед развертыванием. На этом этапе EVALUATING SRT выполняет два принципиально разных типа экспериментов:

  1. Синтетический эксперимент: недорогой тест с низким уровнем риска для выявления очевидных регрессий до развертывания в продакшене.
  2. Производственный эксперимент: оценка в реальных условиях, которая проверяет изменения на разнообразных продакшн-нагрузках для повышения уверенности.

Рекомендация переходит к тестированию в продакшене только после успешного прохождения синтетического эксперимента. Если у подключенной функции есть несколько ожидающих рекомендаций, SRT расставляет приоритеты и сначала оценивает кандидатов с наибольшей потенциальной экономией.

Рисунок 6: Этап оценки

Синтетический эксперимент:

  • Запускается в тестовой среде, изолированной от продакшн-трафика.
  • Создает два кластера: один для текущей конфигурации, другой для рекомендуемой.
  • Одновременное воспроизведение идентичных наборов запросов на обоих кластерах без разделения трафика, что подвергает обе конфигурации воздействию 100% тестовых запросов.
  • Обычно длится 1–2 часа.
  • Выполняется до конца без проверок на досрочное прекращение.

Рисунок 7: Схема синтетического эксперимента

Производственный эксперимент:

  • Запускается в продакшене на реальном пользовательском трафике, разделенном на три потока:
    ◦ ~90% остается на основном кластере (текущая продакшн-конфигурация).
    ◦ ~5% направляется на базовый кластер (текущая продакшн-конфигурация).
    ◦ ~5% направляется на экспериментальный кластер (конфигурация по рекомендации).
  • Оценивает рекомендации путем сравнения с аналогичным по размеру базовым кластером, а не с основным кластером, чтобы сохранить сопоставимые профили трафика.
  • Обычно длится от одного дня до одной недели в зависимости от объема трафика.
  • Быстрое обнаружение сбоев (fail fast): эксперимент досрочно отменяется при обнаружении регрессий.

Рисунок 8: Схема производственного эксперимента

Платформа Stratum выполняет и другие эксперименты наряду с экспериментами SRT. Во избежание чрезмерного разделения трафика эксперименты SRT выполняются с более низким приоритетом и уступают ресурсы активным экспериментам с более высоким приоритетом.

Трафик поступает неравномерными всплесками, разделенными многодневными или многонедельными затишьями. Конвейер проверки адаптируется к этим переменным паттернам поступления, а не рассчитывает на стабильный трафик.

Возвращаясь к нашей рекомендации по памяти для VideoEncoder.encodeV1 (18 000 МБ → 15 300 МБ), проверка запускается со следующими параметрами:

{
"recommendationId": "2edb734a-6184-4f5e-8ffa-23004bd665d7",
"syntheticExperiment": { "numberOfExecutions": 3000 },
"productionExperiment": {
"enabled": true,
"maxContainers": 20, // max containers shift to baseline & experimental clusters
"upGateTimeoutMinutes": 10080, // time to wait for traffic to start flowing
"maxRunDurationMinutes": 1240, // max time to run the experiment once traffic starts
"minSamples": 500 // min executions needed on both clusters before evaluating
}
}

Оба этапа проверки оценивают рекомендации по двум последовательным критериям, немедленно прерывая процесс при неудаче по любому из них:

  • Повторные попытки с большим количеством ресурсов: ограничивает сокращение памяти и диска максимальным порогом повторных попыток в 1% за время проведения эксперимента.
  • Время выполнения: сравнивает медианное время выполнения во избежание искажения результатов выбросами, допуская замедление до 10–15% по сравнению с базовым уровнем в зависимости от рабочей нагрузки (настраивается для каждой функции).

Если рекомендация успешно проходит оба этапа проверки, SRT обновляет ее статус до APPLIED и развертывает конфигурацию на основном продакшн-кластере. Если проверка в любой момент завершается сбоем, SRT помечает рекомендацию как REJECTED и сохраняет существующую конфигурацию. SRT отправляет уведомления об обоих исходах.

Для VideoEncoder.encodeV1 оба этапа прошли успешно:

{
"outcome": "APPLIED",
"syntheticExperiment": {
"result": "SUCCESS",
"samples": { "baseline": 3000, "experimental": 3000 },
"medianExecutionSecs": { "baseline": 59.0, "experimental": 59.0 },
"slownessIncreasePct": 0.0,
"retryRatePct": { "baseline": 0.0, "experimental": 0.0 }
},
"productionExperiment": {
"result": "SUCCESS",
"samples": { "baseline": 50361, "experimental": 49790 },
"medianExecutionSecs": { "baseline": 196.0, "experimental": 198.0 },
"slownessIncreasePct": 1.0,
"retryRatePct": { "baseline": 0.0, "experimental": 0.0 }
}
}

Рекомендация перешла в состояние APPLIED, окончательно закрепив выделение памяти для VideoEncoder.encodeV1 на уровне 15 300 МБ. Мы наблюдали аналогично успешные результаты для рекомендации по ЦП, которая сократила выделение процессорных ядер с 8 до 4.

Проверка рекомендаций

Успешное прохождение проверочных экспериментов не означает завершение жизненного цикла рекомендации. Обновленный код функции, измененные входные параметры или базовые изменения в вычислительной среде (Titus/EC2) могут со временем изменить поведение в продакшене. Чтобы гарантировать безопасность конфигураций и стимулировать внедрение функции, мы внедрили непрерывный мониторинг примененных изменений.

Мы отслеживаем метрики в течение 90 дней в рамках двух скользящих временных окон: 30-минутного короткого окна и 24-часового длинного окна. Каждое окно поддерживает определенные пороги срабатывания оповещений: уровень повторных попыток в 3% за 30 минут или 2% за 24 часа инициирует автоматическое уведомление.

В стационарном состоянии рабочие нагрузки демонстрируют базовую частоту повторных попыток на уровне около 0,1%, а значения до 2%–3% укладываются в допустимые эксплуатационные отклонения. Большинство примененных рекомендаций оставались стабильными в течение последних трех месяцев.

Функция VideoEncoder.encodeV1 работала на оптимизированной конфигурации в течение месяцев без превышения пороговых значений. Тем не менее, VideoEncoder.encodeV2 продемонстрировала сложный крайний случай: сокращение памяти на 50% прошло все проверки и стабильно работало в течение двух недель, пока неожиданное изменение трафика не привело к росту частоты повторных попыток выше 60%.

Рисунок 9: Неожиданный всплеск повторных попыток

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

Сегодня два окна автоматического возврата к исходному состоянию выглядят следующим образом:

  • Последние 30 минут: 3% повторных попыток вызывают предупреждение; 10% инициируют автоматический откат.
  • Последние 24 часа: частота повторных попыток в 2% инициирует как оповещение, так и автоматический откат.

Превышение порога автоматического отката немедленно восстанавливает конфигурацию функции до ее исходного состояния, предшествовавшего рекомендации.

Рисунок 10: Автоматический откат рекомендации

Мы сознательно поддерживаем простую логику отката — восстанавливаем последнюю известную стабильную конфигурацию вместо того, чтобы пытаться выполнять динамическую настройку ресурсов во время инцидента.

Инцидент с VideoEncoder.encodeV2 также изменил наши правила генерации рекомендаций для распределения памяти и дискового пространства. Вместо того чтобы сразу применять целевые сокращения в полном объеме, SRT теперь применяет меньшие, инкрементные изменения шагами по 15%, продвигаясь вперед только после подтверждения стабильности на каждом этапе. Кроме того, мы внедрили глобальный аварийный выключатель (kill switch) для отключения автоматической оптимизации размеров для всех функций в случае неожиданных проблем или побочных эффектов.

Кроме того, мы установили обязательный период охлаждения (cooldown) — обычно равный одной неделе — перед запуском новых экспериментов для функции. Приостановка корректировок позволяет нам наблюдать за производительностью в условиях разнообразных паттернов продакшн-трафика, выявляя потенциальные риски до применения последующих рекомендаций.

Где мы находимся сегодня

Контейнеры избыточного размера и дрифт конфигураций не должны быть неизбежной платой за запуск бессерверных рабочих нагрузок в больших масштабах. Создав Stratum Resource Tuner, мы превратили ручной и рискованный подбор ресурсов в автоматизированный конвейер самовосстановления. На примере реальных рабочих нагрузок и на основе жестких уроков из-за неожиданных всплесков мы доказали, что непрерывная оптимизация размеров может безопасно обеспечить значительный прирост эффективности инфраструктуры.

Изначально мы сосредоточились на оптимизации высокопроизводительных задач кодирования видео, стремясь к первичному снижению общих вычислительных затрат Stratum на 5%. Например, для VideoEncoder.encodeV1 удалось добиться сокращения использования ЦП на 50% и памяти на 40% без ущерба для производительности или частоты повторных попыток.

Тем не менее, такие краевые случаи, как VideoEncoder.encodeV2, подчеркнули ключевые уроки: крупные сокращения за один шаг могут таить в себе скрытые риски, а ручное реагирование на инциденты замедляет восстановление. Эти выводы заставили нас ужесточить правила безопасности в Stratum Resource Tuner, включая ограничение сокращения памяти и диска до 15% за цикл и добавление автоматических откатов при превышении порогов повторных попыток. Руководствуясь этими мерами предосторожности, повторная настройка VideoEncoder.encodeV2 принесла стабильное сокращение памяти на 20% при нулевых последующих инцидентах.

Заглядывая в будущее, мы выделяем следующие ключевые приоритеты:

  • Масштабирование SRT за рамки высокопроизводительных задач кодирования для поддержки более широкого спектра функций и типов рабочих нагрузок.
  • Дальнейшая оптимизация ресурсов в регионах с ограниченной доступностью вычислительных мощностей.
  • Переход от реактивных оповещений к проактивному автоматическому наращиванию ресурсов для функций с их нехваткой.
  • Эксперименты с намеренным увеличением ресурсов для чувствительных к задержкам рабочих нагрузок с целью оценки прироста производительности и сокращения времени выполнения функций.
  • Модернизация сигналов сбоя для событий OOM/OOD от запаздывающих индикаторов к опережающим для повышения точности настройки.

Если решение подобных задач кажется вам интересным, мы открываем вакансии в нашем варшавском офисе. Ознакомьтесь с открытыми позициями здесь.

Благодарности

Особая благодарность Олофу Йохансону, Якубу Карчевскому, Адаму Мазуру, Итану Матье, Розанне Ли, Амее Васани, Жану Бархуйзену, Полу Иеромнимону и Адитье Пракашу.

© Netflix Tech Blog