This post is also available in: Английский
У всех видео сервисов есть две важные особенности: даже при небольшом количестве одновременных зрителей нагрузка становится ощутимой; в случае проблем с доставкой видео пользователи могут перестать пользоваться сервисом. Чаще всего проблемы с доставкой видео связаны с высокой нагрузкой и неоптимальным использованием ресурсов. Для решения такого рода задач в наших проектах мы использовали специальный модуль – балансировщик видеонагрузки. В этой статье мы подробно расскажем про этот балансировщик, а также о том, как построить эффективную видеоплатформу благодаря оптимальному распределению нагрузки.
Основной предпосылкой разработки собственного балансировщика стало принципиальное отсутствие подходящих средств, предназначенных для оптимального распределения нагрузки на видеоплатформах. Мы не нашли даже таких инструментов, которые бы специализировались на решении какой-либо подобной задачи. В итоге, в 2008 году, мы начали проводить эксперименты по эффективному распределению нагрузки на видеоплатформах с применением нашего собственного балансировщика, написанного на С++.
Прежде всего мы решили, что использование низкоуровневых алгоритмов распределения нагрузки (TCP Round Robin, DNS Load Balancing) не сможет нам чем-то помочь, т.к. выбор оптимального видео сервера возможен лишь на основе подробной информации о запрашиваемом контенте. Поэтому включение балансировщика мы сделали отдельным этапом в процессе инициализации воспроизведения видео. При инициализации каждый видеоплеер обращается к балансировщику для определения обслуживающего видеосервера. В некоторых случаях, данную балансировку может выполнить бэкэнд при подготовке HTML-страницы с видеоплеером (т.е. сразу вставить ссылку на видеосервер) или при выдаче информации по видео объекту (например, через JSON).
Основные задачи алгоритма, производящего выбор обслуживающего видеосервера:
1. Обеспечить распределение клиентских запросов по множеству доступных серверов (вообще говоря, существует чрезвычайно много различных инструментов, как программных, так и программно-аппаратных, но с их помощью невозможно учесть все особенности, характерные для доставки видеоконтента)
2. Обеспечить эффективное использование инфраструктуры видеоплатформы, т.е. за счет интеллектуального распределения нагрузки увеличить максимальное число обслуживаемых видеоплатформой пользователей (в сравнении с простым “round-robin”) без снижения качества доставки видео
3. Автоматически поддерживать качество сервиса (выводить из эксплуатации проблемные модули, плавно нагружать введенные в эксплуатацию модули)
Если с первым и третьим пунктом все достаточно ясно – существуют алгоритмы, протоколы, системные параметры, методы оценки эффективности, то на решение задач, связанных со вторым пунктом, усилий было затрачено в несколько раз больше. Популярные программные продукты типа Varnish или NGINX позволяют осуществлять распределение клиентских запросов на основании простых правил, но реализовать с их помощью эффективную балансировку между кэширующими серверами видеоплатформы невозможно.
В рамках нескольких крупных проектов были исследованы традиционные для видеосервисов аспекты распределения нагрузки. Нагрузка при этом неоднородна, но имеет циклический характер (периодичность — день, неделя, месяц), контент пользуется различной популярностью у пользователей, и на популярность контента влияют внешние факторы. Строго говоря, эти факты касаются не только видеоконтента, но в силу развлекательной составляющей основной массы видео, они в данном случае существенно более ярко выражены.
Полученные в результате тестов наблюдения позволяют утверждать, что один и тот же объем трафика можно отдавать с гораздо меньшими усилиями (с точки зрения нагрузки на серверы и стоимости эксплуатации платформы). Один из очевидных способов повышения эффективности видеоплатформы – это перенаправление пользователей на те видеосерверы, на которых нужный контент есть в кеше (желательно, в оперативной памяти).
В настоящий момент основную часть трафика в реализованных нами проектах составляет контент, отдаваемый по протоколам HTTP Dynamic Streaming и HTTP Live Streaming; иногда можно встретить HTTP Progressive Download, но его использование осуществляется лишь с целью поддержки относительно старых ConnectedTV. Таким образом, единица контента с точки зрения кэширования – последовательность файлов (чанков) размером примерно 0.5 – 10 Мбайт (зависит от длительности и битрейта фрагмента видео, которое содержит каждый файл).
Ситуация в отдельных проектах осложнялась резкими пиковыми нагрузками, которые можно легко получить, например, при рекламе по ТВ на широкую аудиторию или при старте популярного спортивного события. На данный момент, наш балансировщик работает в проектах со следующими максимальными параметрами нагрузки:
- 40 видеосерверов (Edge)
- 40 Гбит/с трафика в часы наибольшей нагрузки
- 80 терабайт контента
- Live- и VOD-контент
Архитектура
В типовой схеме видеоплатформы с балансировщиком есть один собственный CDN и, возможно, несколько сторонних CDN. Структурно система балансировки состоит из двух элементов:
1. Video Load Balancer – сервис распределения нагрузки, определяющий оптимальный обслуживающий видеосервер на основании собранной статистики
2. Сервис, работающий на видеосервере (Edge Reverse-Proxy Server) и предоставляющий необходимую статистику сервису балансировки
После запуска балансировщик собирает информацию со всех Edge-серверов о том, какой контент у них есть в кеше, какой уровень использования системных ресурсов на сервере (сеть, процессор, жесткий диск). На основании собранной статистики (которая регулярно обновляется) балансировщик принимает решение, какой контент с какого сервера лучше отдавать. Масштабирование достигается путем установки нескольких балансировщиков и распределения трафика между ними при помощи алгоритма TCP Round Robin.
Алгоритм распределения нагрузки
Система балансировки осуществляет распределение пользователей по списку доступных ей CDN. С точки зрения балансировщика CDN бывают двух видов:
- внутренний – инфраструктура самого видеосервиса (собственные серверы, облачные мощности Amazon EC2 и др.)
- внешний — сторонние сети доставки контента (Akamai, Limelight Networks, Level 3)
При балансировке внутри собственной инфраструктуры балансировщик выбирает конкретный видеосервер (или инстанс в облаке), который обслужит запрос пользователя. В случае принятия балансировщиком решения об отправке пользователя в одну из внешних сетей доставки контента соответствующий выбор ложится на ядро маршрутизации конкретной сети.
Правила, используемые для выбора из множества доступных CDN, определяются рядом параметров и позволяют настроить распределение пользовательских запросов согласно потребностям конкретного проекта. Учитывая стоимость трафика на внешних CDN, можно гибко варьировать приоритеты обслуживания пользователей в зависимости от их статуса, географической принадлежности и статуса запрашиваемых единиц контента, что влияет на качество сервиса и стоимость эксплуатации проекта в целом. Так иногда требуется отправлять в CDN только премиум-контент (например, платный) или только премиум-пользователей (например, тех, кто оплатил подписку). Это позволяет реализовать эффективное использование дорогих CDN сервисов. Другой задачей оптимизации затрат может быть вывод в CDN трафика, превышающего мощности внутренней платформы (краткосрочные пики).
Например, типичная задача по оптимизации затрат на доставку видео, может быть решена использованием комбинации из трех инфраструктурных подходов:
- Полноценные серверы с гарантированным арендованным каналом (обслуживающие средний уровень нагрузки и занятые 95% времени)
- Специальные серверы (инстансы) для обслуживания пиков трафика (на определенном этапе, аренда гарантированной полосы становится невыгодна, т.к. простой в часы наименьшей нагрузки все равно нужно оплачивать полностью)
- Коммерческая CDN-сеть для обслуживания крупномасштабных событий (необходимо для более выгодных условий по трафику, в прайс-листе Amazon самый дешевый трафик стоит по $0.05)
Настройка подобного распределения в ручном режиме может потребовать много времени, кроме того, ее нужно будет постоянно актуализировать под текущий профиль нагрузки. Мы подобные задачи решаем при помощи балансировщика, который может интеллектуально распределять пользователей по уровням в зависимости от текущих нагрузок в проекте, что в конечном итоге приведет к хорошей экономии.
Главной целью интеллектуального распределения пользователей по серверам собственной видеоплатформы является повышение эффективности: достижение максимальной емкости платформы по числу обслуживаемых ею пользователей, повышение качества доставки видеоконтента. На основании данных, полученных в ходе многих проектов, были выявлены особенности характера нагрузки, позволяющие практически в режиме реального времени осуществлять перераспределение пользователей между серверами, таким образом поддерживая качество сервиса и снижая нагрузку на платформу в целом.
Ключевыми параметрами, влияющими на принятие балансировщиком решения при выборе конкретного сервера доставки контента, являются:
- Наличие контента в кэше. Если контент есть в кэше, то Edge-сервер не создает нагрузки на сетевое хранилище и Origin-сервер. Масштабируя платформу по числу Edge-серверов (максимальное число одновременных пользователей), мы с меньшей вероятностью столкнемся с ограничениями производительности сетевого хранилища.
- Загруженность Edge-сервера. Учитывается нагрузка на сетевые интерфейсы, процессор и дисковую подсистему. От производительности дисковой подсистемы зависит, сколько уникальных единиц контента сервер может отдавать одновременно. От сети зависит максимальное количество зрителей, которые могут быть обслужены данным сервером. В свою очередь, объем оперативной памяти определяет, как часто для отдачи контента придется обращаться к жесткому диску.
- Оптимальность маршрута от пользователя до конкретного Edge-сервера. Задается таблицей маршрутизации, разбивающей множество Edge-серверов внутреннего CDN на группы.
- Наличие запрашиваемой единицы контента в списке просматриваемых в данный момент. В этом случае резко возрастает вероятность попадания в файловый кэш операционной системы, а также локализация популярных единиц контента в кэше на меньшем числе Edge-серверов. Как следствие снижается нагрузка на дисковую подсистему и увеличивается число обслуживаемых пользователей без падения качества сервиса.
На практике бывает необходимо модифицировать алгоритм выбора видеосервера в зависимости от информации, полученной от пользователей. Например, в силу ряда обстоятельств может возникнуть ситуация, когда с точки зрения плеера видеосервер, на который его отправил балансировщик, неисправен (например, недоступен). Тогда плеер может повторно запросить Edge-сервер, указав те сервера, которые с его точки зрения не удовлетворяют необходимому качеству обслуживания, и получит в ответ альтернативный вариант.
Интересная функция, позволяющая быстро вывести пользователей с видеосервера без существенного нарушения качества просмотра, требовалась нам практически в каждом проекте. В итоге, для удобства администрирования, был реализован функционал принудительного вывода Edge-серверов из ротации, — в частности, плеер может с заданным интервалом отправлять балансировщику запросы на проверку статуса Edge-сервера, и, в случае необходимости, запрашивать другой Edge-сервер. Это позволяет оперативно освободить от клиентов серверы, нуждающиеся в профилактических работах.
Аппаратная платформа
Конкретные требования, выдвигаемые к аппаратному обеспечению, определяются, исходя из планируемых условий использования. В случае с доставкой VOD-контента мы рекомендуем серверы с быстрой дисковой подсистемой (лучше всего, SSD) и хорошим внешним каналом (например, bond из 4-х сетевых интерфейсов по 1 Гбит/с). За счет правильной настройки системы балансировки можно достичь высокой эффективности кэширования: соотношение исходящего трафика с Edge-серверов и исходящего трафика с NAS в различных проектах с VOD-контентом может превышать 10:1. При этом уменьшается ротация кэша и снижается число циклов перезаписи, что критично для SSD-дисков. Производительность процессора для кэшируещего сервера особой роли не играет. Объем необходимой оперативной памяти также целиком зависит от предполагаемого характера нагрузки и целесообразности увеличения производительности за счет кэширования в памяти.
На рисунке ниже приведена зависимость скорости отдачи фрагментов VOD-контента (в Мбит/с) от числа одновременно просматриваемых единиц контента с одного сервера. Серверы различаются объемом оперативной памяти, помимо прочего, на Node-3 (линия зеленого цвета) в качестве накопителя используется RAID 0 из четырех SSD. Размер файлового кэша на всех серверах одинаков. Для удобства на график выведены аппроксимирующие кривые, отражающие общие тенденции.
До тех пор, пока набор одновременно отдаваемых единиц контента может эффективно обслуживаться при помощи механизмов файлового кэширования операционной системы, мы видим превосходство Node-2 с 64 ГБ RAM. В этом случае, максимальное число пользователей, которое может обслуживать данный узел доставки контента, ограничено только пропускной способностью его сетевых интерфейсов. С ростом числа одновременно отдаваемых единиц контента растет вероятность сбоя файлового кэша, находящегося в оперативной памяти, на графике это отражается в резком снижении производительности всех серверов, за исключением сервера с SSD-накопителями. Последний, в свою очередь, будет уверенно держать нагрузку до тех пор, пока дисковый кэш не начнет активно обновляться, т.е. число одновременно отдаваемых единиц контента не превысит число единиц контента, способное разместиться в кэше. Это с связано с принципиальным выигрышем в скорости произвольного чтения при использовании SSD в сравнении с обыкновенными жесткими дисками.
На основе реальных тестов балансировщик способен обрабатывать свыше 3000 запросов на получение контента в секунду (4 рабочих потока на Intel(R) Xeon(R) CPU E5540 @ 2.53GHz). Масштабирование достигается за счет добавления дополнительных балансировщиков и распределения нагрузки между ними (например, на основе TCP Round Robin). При этом балансировщик, работающий на Micro Instance Amazon EC2, способен обрабатывать в тех же условиях до 800 запросов в секунду. При числе рабочих потоков, равном числу ядер, производительность растет практически линейно. С ростом числа обслуживаемых Edge-серверов линейно растет потребление памяти балансировщиком, но время ответа различается в пределах погрешности измерений.
API балансировщика
Вся статистика, на основе которой балансировщик принимает решения о перенаправлении клиентов, также доступна в рамках API-интерфейса. Его можно непосредственно использовать в своих внутренних системах, либо осуществлять мониторинг и анализировать данные статистики с помощью специального GUI (см. скриншот ниже). В этой утилите реализовано использование API-балансировщика. В частности, помимо наблюдения за состоянием платформы, можно вручную производить перенастройку ряда параметров балансировщика в процессе функционирования системы (на лету).
Еще одним вариантом мониторинга и агрегирования статистики является использование сторонних средств анализа логов балансировщика.
Основные параметры статистики, доступной через API балансировщика, которые нам требовались чаще всего:
1. Число запросов к балансировщику в секунду
2. Число клиентов на каждом Edge-сервере и в целом по платформе
3. Количество уникальных единиц контента, отдаваемых одновременно
4. Суммарный трафик с каждого Edge-сервера и в целом по платформе
5. Значения счетчиков broken edge.
Итоги
Ниже приведены основные функциональные возможности текущего релиза балансировщика:
- Выбор наиболее эффективного сервера для обслуживания запроса пользователя
- Оптимизация затрат на доставку контента
- «Слив» пиков трафика сверх возможностей собственной инфраструктуры в CDN-сети и облачные инфраструктуры (вместо деградации общего качества доставки видео)
- Динамическое изменение конфигурации видеоплатформы «на лету»
- Ручной режим управления трафиком
- Идентификация проблем в инфраструктуре (broken edge)
- Сбор статистики в режиме реального времени
Планы по развитию балансировщика в ближайших релизах:
- Доработка алгоритмов балансировки — максимальная локализация кэшированных единиц контента. Проектирование логики с учетом накопленной статистики по характеру нагрузки для обеспечения максимальной емкости платформы по числу пользователей с минимальными финансовыми затратами (самообучающийся алгоритм). Повышение устойчивости системы в целом: после случайных всплесков система должна быстро приходить в стабильное, с точки зрения кэша, состояние.
- Улучшение интеграции с внешними CDN-сетями – учет статистики из сторонних CDN в процессе балансировки (ограничение бюджета, уведомления и т.п.).
- Развитие средств сбора и визуализации статистики
- Интеграция сервисов определения местоположения для учета данных при балансировке (в дополнение к текущему механизму маршрутов)
Нам очень интересно узнать про Ваши проекты, какие особенности распределения видеотрафика были у Вас.
Коммерческие условия
Система балансировки контента доступна в следующих конфигурациях:
- Лицензия на инстанс балансировщика для Amazon EC2 — $5 в месяц (плюс стандартные затраты на Amazon EC2 сервис)
- Сервис балансировки, работающий на нашей инфраструктуре — $200 в месяц (500 балансировок в секунду = 30.000 запусков видео в минуту)
- Безлимитная лицензия для установки на любом сервере — $4.500