Разработка
Как Prime Video масштабировал службу мониторинга и снизил затраты на 90%
Переход нашего сервиса на монолит позволил снизить затраты на инфраструктуру более чем на 90%. Это также увеличило наши возможности масштабирования.
В Prime Video мы предлагает своим клиентам тысячи live стримов. Чтобы обеспечить бесперебойное получение контента клиентами, Prime Video создал инструмент для мониторинга каждого потока, просматриваемого клиентами. Этот инструмент позволяет нам автоматически выявлять проблемы с качеством воспроизведения (например, повреждение блоков или проблемы синхронизации аудио/видео) и запускать процесс их устранения.
Наша команда по анализу качества видео (VQA) в Prime Video уже имела инструмент для проверки качества, но мы никогда не планировали и не разрабатывали его для работы в больших масштабах (нашей целью был мониторинг тысяч одновременных потоков и увеличение этого числа со временем). При подключении все новых потоков к сервису мы заметили, что использование инфраструктуры в больших масштабах обходится очень дорого. Мы также заметили узкие места в масштабировании, которые не позволяли нам отслеживать тысячи потоков. Поэтому мы сделали шаг назад и пересмотрели архитектуру существующего сервиса, сосредоточившись на стоимости и узких местах масштабирования.
Первоначальная версия нашего сервиса состояла из распределенных компонентов, которые оркестровались с помощью AWS Step Functions. Двумя самыми дорогими операциями с точки зрения стоимости были рабочий процесс оркестровки и передача данных между распределенными компонентами. Чтобы решить эту проблему, мы перенесли все компоненты в один процесс, чтобы передача данных происходила в памяти процесса, что также упростило логику оркестровки. Поскольку мы собрали все операции в один процесс, мы могли использовать для развертывания масштабируемые экземпляры Amazon Elastic Compute Cloud (Amazon EC2) и Amazon Elastic Container Service (Amazon ECS).
Накладные расходы на распределенные системы
Наш сервис состоит из трех основных компонентов. Медиаконвертер преобразует входные аудио- и видеопотоки в кадры или расшифрованные аудиобуферы, которые отправляются детекторам. Детекторы дефектов выполняют алгоритмы, которые анализируют кадры и аудиобуферы в режиме реального времени в поисках дефектов (таких как фриз видео, повреждение блоков или проблемы синхронизации аудио/видео) и отправляют уведомления в режиме реального времени при обнаружении дефекта. Подробнее об этом читайте в статье “Как Prime Video использует машинное обучение для обеспечения качества видео”. Третий компонент обеспечивает оркестровку, которая управляет потоками в сервисе.
Мы разработали наше первоначальное решение как распределенную систему с использованием бессерверных компонентов (например, AWS Step Functions или AWS Lambda), что было хорошим выбором для быстрого создания сервиса. Теоретически это позволило бы нам масштабировать каждый компонент сервиса независимо. Однако то, как мы использовали некоторые компоненты, привело к тому, что мы уперлись в жесткий предел масштабирования на уровне около 5% от ожидаемой нагрузки. Кроме того, общая стоимость всех блоков была слишком высока, чтобы использовать решение в большом масштабе.
На следующей диаграмме показана бессерверная архитектура нашего сервиса.
Основным узким местом в архитектуре было управление оркестровкой, которое было реализовано с помощью AWS Step Functions. Наш сервис выполнял множество переходов состояний за каждую секунду потока, поэтому мы быстро достигли пределов учетной записи. Кроме того, AWS Step Functions взимает плату с пользователей за каждую транзакцию состояния.
Вторая проблема с затратами, которую мы обнаружили, была связана с тем, как мы передавали видеокадры (изображения) между различными компонентами. Чтобы уменьшить вычислительные затраты на преобразование видео, мы создали микросервис, который разбивает видео на кадры и временно загружает изображения в корзину Amazon Simple Storage Service (Amazon S3). Затем детекторы дефектов (где каждый из них также работает как отдельный микросервис) загружают изображения и обрабатывают их параллельно с помощью AWS Lambda. Однако большое количество Tier-1 вызовов к корзине S3 было дорогостоящим.
От распределенных микросервисов к монолитному приложению
Для устранения узких мест мы сначала рассматривали возможность исправления проблем по отдельности, чтобы снизить стоимость и увеличить возможности масштабирования. Мы поэкспериментировали и приняли смелое решение: мы решили перестроить нашу инфраструктуру.
Мы поняли, что распределенный подход не приносит больших преимуществ в нашем конкретном случае использования, поэтому мы собрали все компоненты в один процесс. Это устранило необходимость в использовании корзины S3 в качестве промежуточного хранилища для видеокадров, поскольку передача данных теперь происходила в памяти. Мы также реализовали оркестровку, которая управляет компонентами в рамках одного инстанса.
На следующей диаграмме показана архитектура системы после перехода на монолит.
Концептуально архитектура высокого уровня осталась прежней. У нас остались точно такие же компоненты, как и в первоначальном проекте (преобразование медиа, детекторы или оркестровка). Это позволило нам повторно использовать большое количество кода и быстро перейти на новую архитектуру.
В первоначальном проекте мы могли горизонтально масштабировать несколько детекторов, поскольку каждый из них работал как отдельный микросервис (поэтому для добавления нового детектора требовалось создать новый микросервис и подключить его к оркестрации). Однако в нашем новом подходе количество детекторов масштабируется только по вертикали, поскольку все они работают в рамках одного экземпляра. Наша команда регулярно добавляет новые детекторы в сервис, и мы уже превысили возможности одного инстанса. Чтобы решить эту проблему, мы клонировали сервис несколько раз, параметризуя каждую копию с помощью разных подмножеств детекторов. Мы также реализовали легкий уровень оркестровки для распределения запросов клиентов.
На следующей диаграмме показано наше решение для развертывания детекторов, когда емкость одного экземпляра превышена.
Результаты и выводы
Микросервисы и бессерверные компоненты — это инструменты, которые действительно работают в больших масштабах, но вопрос о том, использовать ли их вместо монолита, должен решаться в каждом конкретном случае.
Переход нашего сервиса на монолит позволил снизить затраты на инфраструктуру более чем на 90%. Это также увеличило наши возможности масштабирования. Сегодня мы можем обрабатывать тысячи потоков, и у нас еще есть возможности для дальнейшего масштабирования сервиса. Перенос решения на Amazon EC2 и Amazon ECS также позволил нам использовать бюджетные планы Amazon EC2, которые помогут еще больше снизить затраты.
Некоторые принятые нами решения не очевидны, но они привели к значительным улучшениям. Например, мы продублировали дорогостоящий процесс преобразования медиафайлов и разместили его ближе к детекторам. В то время как однократное выполнение преобразования медиафайлов и кэширование его результатов может считаться более дешевым вариантом, мы обнаружили, что это не является экономически эффективным подходом.
Внесенные нами изменения позволяют Prime Video отслеживать все потоки, просматриваемые нашими клиентами, а не только те, которые имеют наибольшее количество зрителей. Такой подход позволяет добиться еще более высокого качества и еще более качественного обслуживания клиентов.