Хабрахабр

DevConf: как ВКонтакте шел к своей платформе для live-трансляций

DevConf 2018 состоится 18 мая в Москве, в Digital October. А мы продолжаем публиковать доклады с прошлогодней конференции. На очереди доклад Алексея Акуловича из ВКонтакте, где он поведает о том, о чем внимательные читатели уже догадались по сабжу.

В 2015 году мы использовали стороннее решение. Мы встраивали(embed) его плеер на сайт как youtube и оно работало. Работало не идеально, но на тот момент оно нас устраивало по объему трансляций, который через него можно было пустить, а также по качеству и задержкам, которые оно давало. Но мы из него довольно быстро выросли.
Первая причина — задержки. Когда зрители пишут в чате вопросы, а задержка трансляции 40 секунд, то в большинстве случаев это неприемлемо. Основная задержка происходила в передаче сигнала между компьютерами стримера и зрителем(полезный хабрапост на эту тему). Основные протоколы передачи стримингового видео: RTMP, RTSP, HLS, DASH. Первые два — это протоколы без повторных запросов, т.е. мы подключаемся к серверу и он просто вливает данные стрима. Задержка минимальная, может быть меньше секунды, т.е. с этим все хорошо.

И это создает проблемы. HLS и DASH — это протоколы, основанные на HTTP, делающие новый запрос за каждым фрагментом данных. Это нужно, чтобы обеспечить непрерывное воспроизведение. Когда мы начали воспроизводить первый фрагмент, нам надо сразу запросить второй, чтобы когда закончили с первым, второй должен быть скачан и распарсен. Один фрагмент — это примерно несколько секунд. Таким образом, минимальная задержка по этим протоколам — два фрагмента. Поэтому, добиться приемлемой задержки с этими форматами не получится.

Первый — через наши приложения, когда у нас полный контроль над разрешением, кодеками и т.д. У нас есть два варианта использования стрима. Второй вариант, когда мы даем возможность стримить с чего угодно, каким угодно софтом. И мы можем этот сигнал отдавать зрителям без обработки. Мы принимаем этот сигнал на вход и должны выдать его зрителям в хорошем качестве. Разумеется, у нас в этом случае нет никакого контроля над кодеками, разрешением, качеством. Поэтому сторонний сигнал должен быть обработан нами и отдан зрителю в нужном разрешении. Например, если один игрок стримит игру в 4К качестве, а зритель пытается смотреть по телефону в 3G и ничего не видит, то виноваты будем мы.

Опираясь на вышеперечисленное, мы пришли к таким протоколам:

  • Для передачи без обработки: RTMP, чтобы обеспечить передачу без задержки
  • С обработкой / fallback: HLS, поскольку там и так уже запланированы задержки на обработку/транскодинг.

На тот момент нам были известны такие решения.

Red5

Red5 рассматривали потому, что о нем в команде знали, но с плохой стороны. В итоге даже не стали ее тестить.

Erlyvideo

Erlyvideo. Отечественная разработка. Довольно популярная, разработчики выступали на конференциях. Но они вообще не заинтересовались сотрудничеством. Сказали: качайте, разбирайтесь. Мы же хотели запустить все как можно быстрее, поэтому решили не связываться. Оставили на потом, если ничего лучше не найдется.

Wowza

Wowza на тот момент использовалась в дружественном проекте и была возможность спросить. И мы взяли ее на тесты.

Плюсы: она действительно много чего умеет.

Минусы:

  • «Форум-ориентированное» конфигурирование. Она имеет документацию, но чтобы что-то найти, надо гуглить. А в гугле все ссылки ведут на форумы. И все решения, которые мы нашли, мы нашли на форумах.
  • XML везде. Даже приходилось задавать куски xml в браузерном интерфейсе.
  • Для того, чтобы получать callback на такие простые вещи как “пользователь начал трансляцию”, “закончил”, “проверка авторизации” нужно писать модуль для wowza на java.

Совсем минусы:

  • На тестовую машину(16Gb RAM + 4Gb swap) пустили 4-5 трансляций и сами(без какого-либо пользовательского трафика) смотрели некоторые и wowza заняла всю память и машина засвопилась. Приходилось перезапускать ее каждый день.
  • Иногда wowza “била” стримы, когда стримеры реконнектились. Т.е. она писала запись на диск, но потом сама же не могла ее воспроизвести. Мы писали в саппорт, но они никак не помогли. Пожалуй это стало причиной отказа от wowza. Поскольку остальное можно было пережить.

Nimble Streamer

Еще одна отечественная разработка. Была гораздо более дружественно настроена. Все нужные нам фичи или были готовы, или были запланированы на ближайшее время. Написана на С++ и теоретически могла запуститься даже на Raspberry Pi, т.е. в плане потребления была на голову выше java. Также у них была библиотека для реализации плеера на мобильных устройствах(iphone, android).

Как все выглядит?

  • Бинарник самого сервера. С закрытыми исходниками. Бесплатный.
  • Платные лицензии на транскодер.
  • Платная внешняя панель управления, которая на порядок удобнее панели wowza. По форумам лазить не нужно. Все настраивается мышкой.

Прямо мышкой можно перетаскивать компоненты и все настроили визуально. Или настройка транскодирования и обработки сигналов. Не перезапуская.

Итак, плюсы:

  • Классная панель.
  • Потребление ресурсов несопоставимо лучше, чем wowza.
  • Удобное, хорошее API.
  • Суммарно стоит дешевле чем wowza.

Минусы:

Особенность в том, что Nimble формирует этот файл на лету, на основе того, какой ему пришел запрос. Когда мы стримим в HLS, плеер обращается по HTTP к файлу-манифесту со списком качеств. Если по http, то http. Если пришли по https, то он отдает https-ссылки. Единственное решение — саб-фильтр на уровне nginx, который изменяет адреса ссылок. У нас он стоял не напрямую для зрителей, а за nginx и проблема в том, что зритель приходит по https, а он отдает http-ссылку и плеер не может воспроизвести. Костыль.

При этом доступ к нему идет по whitelist IP без подсетей, а мы хотели туда ходить с подсети примерно в 128 IP. Второй минус в том, что для управления через API запросы отправляется не на сам сервис, а на стороннему сервис Nimble. Пришлось делать прокси для этого API. Форма в панели позволяет вводить по одному IP. Не бог весть какая проблема, но она есть.

Сервер-бинарник синхронизируется с API по расписанию. Есть еще проблема с асинхронным API Nimble. если мы добавляем нового стримера, он создает стрим, настройки по качеству, но обновятся они только через 30 секунд допустим. Т.е.

Текущая архитектура

И мы должны отдать его зрителю в RTMP и HLS. Стример отдает нам RTMP-поток. Мы поставили машины входящего трафика, которые маршрутизируют его на конкретную рабочую машину.

Мы вспомнили, что у nginx есть rtmp-модуль, который позволяет маршрутизировать rtmp-трафик. Сделали это для того, чтобы мы могли производить операции с этими серверами, вроде обновления софта или перезапуска. И мы поставили его в качестве входящей ноды.

Трафик идет на nginx, а дальше он сам проксирует его куда надо. Тем самым, мы закрыли от стримеров всю нашу внутренную кухню. Это пример из документации(без форумов и xml!): На уровне самого модуля есть возможность переписать(rewrite) rtmp-ссылку и перенаправить поток туда.

Несколько входящих серверов сидят на одном IP и на уровне балансировщика трафик распределяется по ним. Он идет по адресу on_publish, тот переписывает адрес на новый и стрим идет по этому адресу.

Мы хотели спрятать от зрителей внутренности. С раздачей тоже самое. По аналогии со входящими, у нас есть раздающие сервера. Чтобы зрители не ходили напрямую на машину, которая обрабатывает видео. Для RTMP используется тот же самый rtmp-модуль. Там тоже используется nginx. И мы поняли, что наша схема… плохая 🙂 А для HLS используется proxy_cache с tmpfs для хранения фрагментов m3u8 и HLS.
Летом 2016 года к нам пришел International(турнир по Dota 2).

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

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

Для того, чтобы направлять юзера на нужные машины, мы на каждый раздающий сервер поставили демона, который опрашивает все машины своего слоя. Это позволило разгрузить по трафику рабочие машины и раздающие сервера. Если в данный момент данная машина перегружена, но демон говорит nginx-у: перенаправляй теперь трафик вон туда.

Ссылка ведет на https. Для возможности перенаправлять юзера мы сделали так называемый rtmp-редирект. Иначе, на другой https. Если машина не нагружена, то она отдаст редирект на rtmp. И плеер знает когда он может играть, а когда должен редиректиться.

Стример стримит на одну из входящих машин, которые для него едины, поскольку они за балансировщиком на одном IP. Конечная схема вышла такой. Входящий сервер выбирает рабочую машину, которая хранит и обрабатывает поток, а также через два слоя раздающих серверов показывает его зрителям.

Там где нам не нужно транскодирование мы используем тот же nginx с rtmp-модулем. При этом не все рабочие машину у нас на Nimble.

Что дальше?

На данный момент у нас каждый день начинается примерно 200 тысяч стримов(в пике 480 тысяч). Около 9-14 миллионов зрителей каждый день(в пике 22 миллиона). Каждый стрим записывается, транскодируется и доступен как видео.

Полностью перейти на SSD, поскольку рабочие машины очень быстро упираются в диск. В ближайшем будущем(которое наверняка уже наступило, доклад то прошлогодний) планируется расшириться до миллиона зрителей, 3 Тб/сек. Вероятно, заменим Nimble и nginx на свой велосипед, поскольку там есть еще минусы, о которых я не упомянул.

Чем присутствие на конференции от просмотра/чтения доклада отличается? Тем, что на конференции можно подойти к Алексею(и не только к нему!) и узнать конкретные детали, которые вас интересуют. Пообщаться, обменяться опытом. Как правило, доклады лишь задают направление для интересных разговоров.

Читателям Хабра регистрация со скидкой. Приходите послушать доклады и пообщаться.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть