Доставка видеоконтента пользователям
Что такое «контент» для видеохостинга? Во-первых, контент видеохостинга – это просто видео, которое представляет собой набор файлов в различных форматах, в частности, в формате FLV для просмотра пользователем через Flash Player. Эти файлы статичны, видеохостинг при загрузке пользователем видеоролика осуществляет конвертацию во все требуемые форматы с необходимым битрейтом. Хранение такого контента — это хранение обычных файлов, только довольно большого размера. Отдача контента — это, по сути, организация скачивания файлов. Во-вторых, контент видеохостинга — это «живые» потоки или вещания. Вещания не записываются на диск, не происходит их конвертация, потоки раздаются клиентам с учетом пропускной способности каналов (происходит пропуск пакетов, если канал клиента недостаточен для получения потока вещания в полном качестве). Отдача контента в данной ситуации — это раздача потока на большое количество подключенных пользователей (тысячи смотрящих).
Кроме как таковой задачи отдачи контента (корректность, работа под нагрузкой и т.п.) актуальной является проблема «приближения» контента к пользователю. Необходимо организовать доставку контента так, чтобы пользователь получал видео или вещание с сервера, который расположен близко к нему с точки зрения пропускной способности сетевых каналов, а также с точки зрения стоимости трафика для пользователя.
Данная статья, написанная по материалам доклада на конференции «РИТ: Высокие нагрузки»-2008, расскажет об одном из возможных подходов к решению поставленных задач. Рассказ будет основан на нашем опыте проектирования, разработки и поддержки видеохостинга Smotri.Сom, который является сегодня самым крупным видеохостингом Рунета. Описываемые подходы могут быть применимы в областях с похожими характеристиками контента: достаточно большой объем файлов, много файлов, различные виды вещаний и т.п.
Статья будет состоять из двух частей: в первой части речь пойдет об организации файлового хранилища для видеофайлов и об общих аспектах организации вещания. Во второй части будет представлен способ организации CDN (Content Delivery Network), то есть способ «приближения» контента к конечному потребителю, а также применение этого подхода к доставке статических файлов (файлов видео) и к потоковой трансляции (вещания).
Видео: организация файлового хранилища
Видеофайлы
Видеохостинг в процессе своего функционирования получает видео в различных форматах, которое загружается пользователями. Кроме хранения оригинального видеофайла, видеохостинг осуществляет конвертацию файла в ряд форматов: FLV, 3GP, MP4 и т.п. Все эти файлы необходимо хранить на файловых серверах, а также отдавать пользователям. Рассмотрим сначала вопрос хранения таких файлов.
Что представляют из себя эти файлы? Согласно нашим расчетам, в среднем для хранения одной секунды видео требуется 250 Кб дискового пространства (имеется в виду 250Кб/с на все форматы видео вместе взятые), при этом средняя длительность видео составляет примерно 4 минуты. Легко посчитать, что для хранения 1 млн. видеофайлов нам потребуется 60 Тб дискового пространства, что является уже достаточно внушительной цифрой. Этим объемом хранения надо эффективно управлять, а также обеспечивать раздачу такого объема контента пользователям. Кроме непосредственно видеофайлов нам придётся хранить и отдавать вырезанные из видео кадры, которых в нашем случае будет 15 штук: 5 кадров, вырезанные из разных участков видео, каждый из которых представлен в трех различных размерах (для показа информации о видео в блоках разного формата).
Доступ к файловому серверу через WebDAV
Непосредственно за хранение файла отвечает файловый сервер, в котором есть достаточно хорошо построенная дисковая подсистема в плане надежности и скорости доступа (RAID). Запросы на изменение файлов (создание новых файлов, удаление старых и т.п.) поступают с другой группы серверов: с «морд» (frontend) и с перекодировщиков. Морды – это обычные сервера, которые обслуживают подавляющее большинство запросов по HTTP как непосредственно к самому сайту, так и к его API. Перекодировщики принимают запросы от пользователей на загрузку исходных файлов видео и осуществляют их конвертацию. Итак, на морде или перекодировщике формируется заказ на операцию с файлами на файловом сервере, т.к. файловая система не является локальной, необходимо то или иное сетевое средство доступа к файловому серверу.
Самое простое решение – это NFS, которое может сохранить для кода сайта «ощущение», что файлы находятся локально, забирая при этом на себя все сложности по выполнению удаленных операций через сеть. Однако NFS может вести себя крайне ненадежно при падении сетевого соединения между мордой и файловым сервером, а также в силу того, что и морд, и файловых серверов десятки, количество кросс-маунтов NFS становится слишком большим.
Самым простым решением в такой ситуации может быть WebDAV. WebDAV является расширением HTTP, который, кстати, изначально предполагал, что содержимое World Wide Web является не статичным, а изменяемым. WebDAV делает еще один шаг вперед, добавляя в HTTP полноценные возможности по удаленному изменению, созданию, удалению файлов, каталогов, получению информации о файлах и т.п.
Внутри кластера серверов видеохостинга обращение к файловым серверам идёт по протоколу WebDAV. Скачивание файлов (в том числе проигрывание видео в Flash Player) идёт напрямую с файлового сервера, что позволяет более равномерно загрузить сетевые каналы, исключая «лишние» промежуточные звенья.
Выбор файлового сервера из кластера
Предположим, у нас есть кластер файловых серверов, все настроены, готовы отдавать файлы, а также принимать новые файлы через WebDAV. Было загружено видео. Какой файловый сервер выбрать для хранения очередного файла? Выбор можно осуществить, например, на основе следующих характеристик:
- объем свободного места/объем сервера;
- нагрузка на сервер (как измерять?);
- случайный выбор.
Примером плохой стратегии является стремление заполнить все сервера так, чтобы процент занятого места на сервере (или просто объем свободного места) был равным среди всех серверов кластера. При таком подходе обеспечивается равномерное заполнение серверов, однако на практике проект начинается с нескольких файловых серверов, затем добавляются еще и еще, и получается, что при добавлении нового сервера в кластер все новые файлы складываются именно на этот сервер (так как на нем в данный момент больше всего свободного места). А новые файлы чаще всего оказываются и самыми популярными в данный временной отрезок, поэтому нагрузка на новые файловые сервера в такой конфигурации многократно возрастает.
Гораздо более удачной является такая стратегия: среди всех файловых серверов выбираются те, уровень заполнения которых не достиг некоторой критической отметки (т.е. те сервера, на которых еще есть свободное место), а затем среди них осуществляется случайный выбор (возможно, выбор с учетом веса сервера). При такой стратегии популярные видео оказываются равномерно распределенными среди большего числа серверов, что позволяет более равномерно распределить нагрузку по скачиванию контента.
Необходимое ПО
Описанный выше подход требует простого и распространенного программного обеспечения: для скачивания файлов подойдет любой «быстрый» HTTP-сервер, например, nginx, lighttpd и т.п. При этом для обеспечения подгрузки FLV в плеер с любой временнóй отметки (так называемого «стриминга»), нам необходимо очень простое расширение, которое сегодня присутствует как в nginx, так и в lighttpd (flv-streaming). В качестве WebDAV-сервера подойдет Apache httpd и т.п. Для доступа к файлам по WebDAV можно использовать любой WebDAV-клиент, который есть в том или ином виде практически во всех языках программирования. Так, например, в PHP он реализован в виде PEARовского класса (который приходится «допиливать», чтобы обеспечить разумную производительность). WebDAV не обеспечивает функциональности по получению объема свободного места на диске, но это легко обойти с помощью простейшего скрипта в cron, который вывод команды df перенаправляет в файл в корне файлового сервера, а этот файл уже можно скачать по HTTP с любой морды.
Кросс-бэкап
Каким образом обеспечить надежное сохранение 60 Тб данных? (При условии, что эта цифра будет расти?) Традиционные варианты с бэкапом на центральный сервер уже не подходят, т.к. такой объем хранения на одном сервере обеспечить трудно, да и надежность такой схемы невысока. Никакой уровень RAID в пределах одного сервера не может гарантировать надежность, т.к. возможен и аппаратный, и программный сбой, приводящий к потере данных. Простым и достаточно надежным способом является кросс-бэкап: каждый из файловых серверов заполняется наполовину, а затем содержимое первого сервера бэкапится на второй, и наоборот. Таким образом, если произойдет сбой на одном из серверов, на втором останется полное содержимое обоих серверов.
Для реализации данного подхода необходим простой управляющий модуль, а также rsync. При использовании кросс-бэкапа интересным является то, что по одной информации о свободном и занятом пространстве на файловом сервере невозможно судить о его заполненности, т.к. после выполнения синхронизации бэкап-части возможно произвольное увеличение объема хранения (если заранее неизвестна разбивка: сколько места занимают сами данные, а сколько занимает бэкап другого сервера).
Вещания: ретрансляция
Подробный рассказ про организацию вещаний и нашем сервере вещаний был уже представлен на конференции РИТ-2008, поэтому здесь я не буду повторяться и вдаваться в подробности, остановлюсь лишь на основных аспектах.
Вещание представляет из себя видео и аудио потоки, которые кодируются на стороне клиента с помощью Flash Player, затем с помощью протокола RTMP отправляются на сервер вещаний, который раздает эти RTMP-потоки всем подключенным к вещанию зрителям. Здесь основной проблемой является то, что поток раздается клиентам хоть и без перекодирования (в качестве и с битрейтом, заданным автором трансляции), но количество клиентов, подключенных к вещанию, может составлять тысячи человек. При этом каждому клиенту может доставляться измененный поток в соответствие с пропускной способностью каждого клиента (пропуск пакетов в потоке). Кроме того, в RTMP-потоке кроме собственно потока вещания происходят удаленные вызовы процедур (сервер-клиент или клиент-сервер), а также транслируется состояние разделяемых объектов между всеми подключенными к вещанию клиентами.
Один сервер не всегда может справиться с задачей раздачи потока вещания, поэтому мы прибегаем к ретрансляции: автор вещания подключается к первичному серверу вещаний, к которому в качестве клиентов присоединяются другие сервера вещаний, которые уже в свою очередь раздают поток конечным зрителям вещания. При такой схеме оказывается возможным равномерно распределить нагрузку между серверами вещаний (количество клиентов на каждом сервере оказывается примерно одинаковым).