Платформа Видеосервиса На Квартальный Период

Сегодня мы расскажем, как нам удалось за 3 месяца построить нашу платформу видеосервиса в Одноклассниках на Java. Начнем с того, что такое видеосервис в Одноклассниках.

Он доступен как в Интернете, так и в версиях для мобильных устройств.

Одним из отличий «Одноклассников» от других социальных сетей является наличие видеовитрины, где видео собраны в разделах «ТОП недели», «Новинки» и каналов.

Для этих разделов видео подбираются автоматически по умному алгоритму, исходя из количества просмотров, классов и скорости роста популярности видео.

И конечно, в витрине представлены каналы с контентом от партнеров: сериалы, сериалы, мультфильмы и фильмы.

По сути, это стандартный видеосервис.

Пользователь загружает видео, затем оно проходит модерацию, после чего его могут посмотреть другие пользователи.

Видеосервисом в Одноклассниках пользуются более 10 миллионов уникальных пользователей в день, которые просматривают более 70 миллионов видеороликов и скачивают 50 тысяч видеороликов в день.

В видеобазе «Одноклассников» содержится более 28 миллионов видеороликов.

Исходящий трафик по вечерам достигает 80 гигабит в секунду.

Ежедневно загружаемые 5 терабайт нового видео конвертируются в наш внутренний формат, и на выходе получается 2 терабайта.

Полученные файлы сохраняются в трёх копиях, что в итоге составляет 6 терабайт нового видео в день.

Входящий трафик загрузки достигает 2 гигабит в часы пик.



Платформа видеосервиса на квартальный период

На чем все это работает? Сейчас парк видеосервиса насчитывает около 200 серверов, а скоро их станет значительно больше.

Хранилище занимает 70 серверов, общий объем — 5 Петабайт. 30 серверов хранят метаданные, это база данных и кэши перед ними.

Еще 60 серверов занимаются преобразованием пользовательского видео в наши форматы.

Еще 30 серверов предназначены для скачивания и распространения.



Платформа видеосервиса на квартальный период

Мы начали развивать видеосервис на «Одноклассниках» еще в 2010 году.

Поначалу у нас не было собственной платформы и мы разрешали пользователям только делиться ссылками на контент, который находился на других ресурсах: Rutube, YouTube, Mail.Ru Video. В 2011 году мы запустили загрузку видео через портал «Одноклассники», но на платформе «Мэйл.

Ру Видео» все это работало.

Сервис начал расти, стали предъявляться новые требования, и в январе 2013 года мы поняли, что без создания собственной видеоплатформы наш сервис не сможет развиваться дальше.

Новая платформа – новые требования.

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

Далее идет возобновляемая загрузка.

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

Мы хотели увидеть все это на мобильных устройствах.

Мы также любим и умеем управлять сервисами на Java, поэтому это тоже было добавлено в список требований.



Платформа видеосервиса на квартальный период

Давайте посмотрим, как выглядит весь видеоконвейер изнутри.

Пользователь загружает видео на сервер загрузки (обозначим его на картинках стрелкой вверх).

Далее видео попадает в серверное хранилище, а затем на сервер трансформации.

На нем мы конвертируем видео в свой внутренний формат, сохраняем его во временное хранилище, после чего сервер загрузки (стрелка вниз) раздает этот контент пользователям.



Платформа видеосервиса на квартальный период

Рассмотрим подробнее реализацию каждого этапа.

Загрузка Еще раз напомню требования.

Мы хотели реализовать возобновляемую загрузку и обеспечить отказоустойчивость в случае потери сервера.

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

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

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

Платформа видеосервиса на квартальный период

Как выглядит наша система балансировки видеонагрузки? У нас 6 серверов, по 2 в каждом датацентре.

Для балансировки нагрузки внутри дата-центров мы используем LVS (Linux Virtual Server).

Это позволяет хранить за одним IP-адресом множество серверов и пересылать к ним запросы в зависимости от их загрузки.



Платформа видеосервиса на квартальный период



Платформа видеосервиса на квартальный период

Чтобы обеспечить отказоустойчивость центров обработки данных, мы используем DNS-GSLB. Пользователь нажимает кнопку «Добавить видео», получает ссылку на скачивание, а затем доменное имя авторизуется на IP-адресе одного из дата-центров.

DNS-GSLB — это глобальная балансировка нагрузки сервера, ее основная функция — обеспечение отказоустойчивости на уровне центра обработки данных.

В случае сбоя дата-центра наш DNS не будет разрешать (разрешать) доменное имя этому дата-центру.

Еще раз: при выходе из строя сервера пользователь переводится на другой, а при выходе из строя всего дата-центра новым запросом через DNS возобновляется загрузка через другой дата-центр.

Насколько это удобно? Потому что, во-первых, мы не пишем код, а используем готовые решения, а во-вторых, это позволяет нам балансировать нагрузку на любые stateless-сервисы.



Платформа видеосервиса на квартальный период

Теперь поговорим о том, как мы реализовали службу без сохранения состояния.

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

Сервер загрузки реализован на Java с использованием Apache Tomcat.

Платформа видеосервиса на квартальный период

Что происходит, когда мы теряем сервер, дата-центр или, например, пользователь просто восстановил соединение через некоторое время после потери соединения? Наш новый сервер загрузки, не имеющий сеанса с этим пользователем, по состоянию распределенного хранилища определяет последние успешно загруженные байты и возобновляет загрузку с точки отключения.

Отказоустойчивость практически стопроцентная.

Даже если дата-центр потерян в процессе загрузки, процесс возобновляется с того места, где произошел обрыв.



Платформа видеосервиса на квартальный период

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

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



Платформа видеосервиса на квартальный период

При выборе формата мы проанализировали следующие данные: текущая распространенность браузеров и операционных систем, включая Android и iOS, возможность воспроизведения в них видео через HTML5 и Flash. Поскольку текущий плеер Одноклассников реализован на Flash, мы решили поддерживать как HTML5-видео, так и Flash.

Платформа видеосервиса на квартальный период

Рассмотрев форматы, которые поддерживают Flash и HTML5, мы выбрали MP4, в качестве медиаконтейнера кодек H264 и аудиокодек AAC.

Платформа видеосервиса на квартальный период

Итак, после успешной загрузки видео его следует конвертировать в наш внутренний формат. Это делается на серверах трансформации, где мы используем собственную библиотеку FFMpeg. На данный момент у нас около 60 серверов трансформации.

Что происходит с видео? Сервер загрузки загружает видео во временное хранилище и в конце загрузки добавляет в очередь задачу преобразования.



Платформа видеосервиса на квартальный период

Задачи распределяются по серверам, но дело в том, что FFMpeg — штука довольно нестабильная, иногда зависает, съедает все системные ресурсы, бывают случаи, когда видео не конвертируется с первого раза.

Поэтому мы добавили постоянное отслеживание статуса запущенных задач.

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

В случае сбоя сервера задание перезапускается или возвращается обратно в очередь и передается на другой сервер.

Все хорошо, но предыдущий сервер мог просто потерять связь.

И мы не хотим, чтобы сервер выполнял лишнюю работу при восстановлении соединения, что уже делает другой сервер.

Для этого каждый раз при проверке очереди мы отвечаем возвратом возможности продолжать работу.

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

Очередь отвечает, что задача больше не актуальна, и сервер берется за новую задачу.

Эта схема прекрасно работает, но мы получаем Единую Точку Сбоя, это наша очередь.

Если мы потеряем дата-центр, где храним очередь, или сам сервер, то у нас возникнут серьезные проблемы.

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

Мы просто использовали Zookeeper, который «Одноклассники» очень активно использует в других своих сервисах.

Что такое Зоокипер? Это сервер распределенной блокировки, у него есть готовые решения в виде выборов лидера.

Выборы лидера — это процесс в распределенной системе, при котором в случае потери сервера вся система вернется в стабильное состояние за счет назначения «лидера».

Он знает, что он «лидер», и все серверы тоже это знают.

Платформа видеосервиса на квартальный период

По сути, в этой системе «кандидат1» и «кандидат2» ничего не делают, это всего лишь резервные серверы, расположенные в других дата-центрах.

Очередь полностью выполняется на «лидере».

Если «лидер» теряется, избирается новый, и вся система узнает, что новым «лидером» стал первый кандидат.

Платформа видеосервиса на квартальный период

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

Однако состояние очереди на момент падения старого лидера для нового лидера неизвестно.

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

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

Этот период задержки составляет десятки секунд и не оказывает заметного влияния на пользователей.

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

Парсер MP4 .

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

хранилище.

В процессе создания версий разного качества мы столкнулись с этой проблемой.

Оказалось, что 15% загруженных видео в заголовке имеют неправильную длину.

То есть, например, в названии видео указана продолжительность 2 часа, а на самом деле видеопоток длится всего пару минут. Столкнувшись с этим, нам пришлось рассчитывать длину по кадрам; мы используем этот параметр как при расчете выходных параметров видео, так и для нарезки превью.



Платформа видеосервиса на квартальный период

Хранилище После обрезки видео оно отправляется на хранение.

Сейчас он состоит примерно из 70 серверов, каждый из которых имеет 36 двухтерабайтных дисков.

Всего 5 петабайт. Хранилище распределенное, отказоустойчивое, оно называется One Blob Storage (OBS).

Мы используем Zookeeper для хранения состояния кластеров.

Видео хранятся на дисках блоками по 64 мегабайта.

Для этого хранилища выход из строя жесткого диска не является проблемой.

На серверах есть дополнительные диски.

При выходе из строя одного из них другой автоматически восстанавливается до своего состояния.

Мы храним каждое видео в трех экземплярах.

Таким образом, из каждого видео получается четыре новых, каждое из которых сохраняется в трех экземплярах, по одному в каждом ДК.



Платформа видеосервиса на квартальный период

Распространение контента Наверное, самая интересная часть.

Требования:

  • Загружайте видео в любой момент без предварительной буферизации.

  • Высокая производительность, мы ожидали около 150 гигабит в секунду.

  • Отказоустойчивость.



Платформа видеосервиса на квартальный период

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

Но nginx работает с файлами, а мы хотели кэшировать только то, что на самом деле просматривает пользователь.

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

Мне пришлось снова писать свое решение на Java. Давайте сначала посмотрим, что такое псевдопотоковая передача.

При воспроизведении видео в нем присутствует какая-то буферизованная часть.

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

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

Итоговый результат выглядит следующим образом: у нас есть заголовок и есть блоки.

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

Заголовок указывает начало каждого блока.



Платформа видеосервиса на квартальный период

С одной стороны, выгодно использовать много таких блоков.

Но затем объем заголовка растет, а это тот объем, который пользователь вынужден скачать до появления первого кадра видео.

Пытаясь оптимизировать заголовок, мы пришли к следующему решению: максимальный размер заголовка видеофайла не должен превышать 6 Мегабайт. При этом одно видео производит 500-700 блоков.

В процессе нарезки помимо выбора частоты синхронизации видео и звука появилась еще одна проблема.

Стандартные видеоконвертеры обычно помещают заголовок в конец файла.

Для них это гораздо удобнее, поскольку уже известны все смещения всех блоков.

А в случае с потоковым видео главное не забыть переместить заголовок в начало.

Псевдо-потоковая передача Давайте посмотрим на реализацию псевдопотоковой передачи в HTML5. У плеера есть moovatom, при выборе места он вычисляет расстройку, запрашивает данные по байтовому диапазону и обеспечивает нативный поиск.

Для Flash плеера ситуация несколько хуже, он просто при запуске делает запрос к серверу (в URL указано время запуска в секундах), а затем сервер должен подготовить для него полноценный видеофайл, начиная с этого момента.

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



Платформа видеосервиса на квартальный период



Платформа видеосервиса на квартальный период

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

Мы решили, что будем кэшировать видео блоками по 256 килобайт. И все это мы будем делать на Java.

Платформа видеосервиса на квартальный период

Давайте посмотрим на архитектуру нашего дистрибьютора.

Это уровень кэширования между нашим постоянным хранилищем; он имеет несколько уровней кэшей.

Исторически нам было выделено около 96 ГБ оперативной памяти на наших серверах.

Сюда же устанавливаем SSD-накопители.



Платформа видеосервиса на квартальный период

Алгоритм работает следующим образом: пользователь запросил видео с сервера; если оно кэшировано в памяти, то отдаем, если нет, то проверяем диск; если его нет, то идем в свое хранилище.

Мы сразу помещаем видео из хранилища в оперативную память и раздаем пользователям.

В оперативной памяти мы используем только LRU-кеш и при выселении проверяем счетчик, сколько у нас просмотров этого сегмента.

Если сегмент был просмотрен более определенного количества раз, то мы сбрасываем его на диск; Если сегмент просматривался мало, мы его отбрасываем.

Требования для кэша 96 ГБ:

  • Кэш не должен оказывать никакого влияния на GC, это должен быть LRU. Сейчас наш сервер обрабатывает около 20 тысяч запросов в секунду, то есть он должен быть высокопроизводительным.

  • Кэш должен быть постоянным, то есть он должен сохраняться после перезапуска или обновления службы распространения.

У нас более низкие требования ко второму уровню кэширования диска.

Достаточно использовать кэширование FIFO; также используется внутреннее решение OBS, только локально.



Платформа видеосервиса на квартальный период

Большие объёмы в 100 гигабайт и запрет на влияние на GC приводят нас к кэшированию offheap. В принципе, существует множество вариантов кэширования вне кучи.

Есть файлы, отображаемые в памяти через Direct ByteBuffer, но с ними есть проблемы.

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

Конечно, их можно собрать из кубиков, но это будет не очень удобно.

Вариант решения: использовать разделяемую память, для доступа к ней использовать Unsafe. Все это реализовано на нашей открытой библиотеке one-nio, ее можно посмотреть по адресу github .



Платформа видеосервиса на квартальный период

Для распределения мы используем селекторы.

Наш HTTP-сервер является частью библиотеки one-nio. Сервер оснащен двумя гигабитными оптоволоконными картами.

Он имеет 10 карт Gigabit Ethernet для доступа к хранилищу.



Платформа видеосервиса на квартальный период

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

При этом нагрузка на процессор составляет около 30%.

Наши инженеры сейчас работают над перенастройкой системы и началом дальнейшего распространения.

Основное ограничение — 6 слотов на одном сервере и эффективность нашего кэша.

У нас получилось где-то 80/20: 80% запросов блоков берутся из кеша, 20% запросов получаются из OBS. Вероятно, это неплохо, но для 20-гигабитной сети мы почти полностью ориентируемся на ресурс доступа 4-гигабитного Ethernet к нашему постоянному хранилищу.

Балансировка Все бы здорово, но нашим пользователям уже не хватает 20 гигабит. Для раздачи видео мы используем кластеры всех серверов, а также стандартный алгоритм балансировки, который мы ранее учитывали при загрузке видео.

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



Платформа видеосервиса на квартальный период

Нам нужно было сделать так, чтобы на 10 серверах общий размер кэша составлял около терабайта.

Для этого мы написали собственный балансировщик.

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

Фактически каждый сервер раздает только свой видеоконтент. Для обеспечения отказоустойчивости (равномерного распределения нагрузки между другими серверами кластера) мы добавляем реплики в каждый раздел.



Платформа видеосервиса на квартальный период

Если Сервер упал, то раздача происходит по этому разделу с одного сервера, и по другому разделу с другого.

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

Он может не выдержать этого, особенно в часы пик.

Для этого мы «прогреваем» разделы на будущее, то есть иногда с некоторой вероятностью отправляем пользователя на реплики — на реплику1 или реплику2. Таким образом мы убиваем двух зайцев: прогреваем этот кеш и балансируем нагрузку на хранилище, а с другой стороны эффективно используем кеш внутри кластера.

Также не забывайте, что на этом HTTP-сервере легко реализовать диапазон байтов, а вот перестроить атом moov из какого-то места — не самая простая задача.

Сама перестройка происходит на серверах распространения.

Для этого мы попробовали использовать парсер MP4, но он генерировал много мусора, сильно влиял на сборку мусора и был крайне неэффективен.

У нас есть сотни запросов на перемотку в секунду.

Мы отказались от парсера MP4 и реализовали наше решение на Java, чтобы на некоторое время перестроить атом moov. Это оказалось чрезвычайно эффективно, заголовок перестраивается из 6 мегабайт в 3 за время до десяти миллисекунд. Есть интересный факт: в августе 2012 года, когда марсоход приземлился на Марс, НАСА решило организовать онлайн-видеотрансляцию.

Для этого они пригласили nginx. У Nginx была платформа распределения и кэширования, развернутая на 40 серверах Amazon-EC2. Это, конечно, не сверхпроизводительные сервера, но 40 штук – это вполне серьёзно.

Для проверки нагрузки на этот видеосервис была приглашена тестирующая компания, и они протестировали нагрузку около 25 гигабит в секунду.

Я думаю, что один из наших серверов после некоторых доработок выдержит 25 гигабит в секунду.

Они отключали серверы.

Сначала вынесли 10 серверов, трафик немного упал, перебалансировали и вернули в норму.

Выключили еще 10 серверов, трафик упал и не вернулся к 25 гигабитам, а остался на уровне 12 гигабит в секунду.

Оказалось, что раздача на nginx была, конечно, раздачей потокового видео, но видеополоса у них была только одна.

20 серверов обеспечили производительность около 12 гигабит.

Платформа видеосервиса на квартальный период

Ниже представлены основные этапы нашего проекта.

Стоит отметить, что мы начали разработку в январе 2013 года, а в мае 2013 года вся Java-платформа была запущена на 100% порталов.



Платформа видеосервиса на квартальный период

Технологии Мы постарались максимально использовать разработанные нами технологии.

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

Мы решили сэкономить на интеграции и запуске.

С другой стороны, мы использовали очень мало технологий; это наша внутренняя библиотека One-nio, которая доступна в открытом исходном коде.

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

Единственным альтернативным решением был FFMpeg, который использовался для обрезки видео.



Платформа видеосервиса на квартальный период

Собственно, именно так все эти технологии и распределяются по нашим серверам.

Все, кроме FFMpeg, — это Java.

Платформа видеосервиса на квартальный период

Результаты Мы обеспечили полную функциональность услуги в случае потери дата-центров и серверов.

Мы предоставили пользователям возможность возобновить загрузку видео в течение 12 часов после потери соединения.

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

Также мы обеспечили просмотр видео с любого момента времени в форматах Flash и HTML5. Последнее очень важно для мобильных устройств.

Мы добились интересных результатов по трафику с одного сервера.



Платформа видеосервиса на квартальный период

Наши основные планы на ближайшее время — попробовать дополнения для HTML5-плеера.

Вы также можете улучшить работу FFMpeg с кодеками.

Мы получаем много интересных метаданных из видео, загружаемых пользователями, например GPS, но мы пока никоим образом не используем координаты GPS.

Платформа видеосервиса на квартальный период

И еще несколько слов о видеоплатформе Мы разрешаем пользователям Одноклассников загружать видео размером до 8 гигабайт, что в четыре раза превышает максимальный размер видео, разрешенный для загрузки во ВКонтакте.

Причем продолжительность загружаемого видео никак не ограничена (на YouTube, например, для некоторых аккаунтов установлено ограничение в 15 минут).

Максимальное разрешение видео, правда, меньше, чем хотелось бы — всего 720p, что, впрочем, соответствует стандарту HD. Однако вскоре мы обзаведемся новыми мощностями, которые позволят поднять качество до желаемых 1080p. Кроме того, в отличие от других видеоресурсов, сервис «Одноклассники» поддерживает расширенный набор видеоформатов — их более 20, включая .

evo и .

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

Мощный бэкенд в виде разработанной нами видеоплатформы позволил реализовать полноценный онлайн-кинотеатр на Одноклассниках.

Лицензионный контент, который мы получаем от наших партнеров, доступен Теги: #видеосервис #одноклассники #mail.ru #java

Вместе с данным постом часто просматривают: