Cистема хостинга медиа

После статьи об архитектуре connect.ua многие спрашивали о подсистеме обслуживания медиа файлов, поэтому в этой статье речь пойдет о масштабируемых и производительных системах обслуживания медиа.
Что такое подсистема хостинга медиа вообще? Это часть системы, которая отвечает за загрузку, сохранение, преобразование (транскодирование) и отдачу медиа файлов. Зачастую эта система является наиболее ресурсоемкой ввиду больших объемов данных и процессорных затрат.
Самое главное
Обязательно изолируйте подсистему отдачи медиа от основной части Вашей системы, иначе любые затычки в этой подсистеме (которых обычно очень много) будут непосредственно влиять на все остальные части Вашего сайта.
Оборудование
Как всегда перед Вами выбор - покупать дорогой комплекс (файловый супер сервер) либо строить систему из дешевых серверов. Как всегда выбор падает на второй вариант, так как:
- Решение обладает бесконечной масштабируемостью
- Отсутствует единая точка сбоя (SPOF), делая это решение очень устойчивым к сбоям
- Динамику наращивания железа легко контролировать
- Дешевое оборудование - дешевое все остальное (коммутаторы, поддержка, замена и т.п.)
По сравнению с дорогостоящим комплексом, такое решение обладает единственным недостатком: реализацию самой подсистемы распределения файлов придется разрабатывать самим. При грамотном подходе это вовсе не большой кусок работы. На connect.ua переход на такое решение занял около недели (на тот момент у нас было 2.5 Тб данных).
Система репликации позволяет избежать установки дорогостоящих RAID контроллеров и уменьшает вероятность сбоя системы практически до нуля.
Архитектура
Перед нами стоят следующие задачи:
- Загрузка файлов
- Траскодирование файлов
- Распредение файлов по серверам
- Выдача файлов
В общем плане схема работы подсистемы такова:

Теперь детальнее. У нас есть ряд серверов-хранилищ, каждый из которых ничего не знает о всех остальных. Все они доступны извне под определенным адресом (например, m1.connect.ua, m2.connect.ua и т.п.). После получения файла (загрузка пользователя) на бекенд, мы выбираем из набора серверов тот, на который мы сохраним файл. Выбор делается на основе предпочитаемого критерия (случано; учитывая свободное место; учитывая загрузку процессора и т.п.).
Если на каком либо сервере заканчивается место, его можно просто исключить из набора. Поскольку система хранения и выдачи файлов очень не критична к процессору, то его можно хорошо утилизировать процедурой транскодирования. В этом случае все загруженные файлы будут попадать на транскодеры, после чего будут перемещены на финальные сервера.
Репликация
Для обеспечения стабильной работы применяется репликация на уровне приложения.
В этом случае все файлы сохраняются не на один, а на несколько серверов. При выходе одного сервера из строя, файл все равно будет доступен с другого. Имеет смысл копировать все файлы на два сервера, т.к. возможность выхода из строя сразу двух серверов очень мала. Выбирать более чем два сервера для копирования не обосновано в терминах затрат на объем хранилища.
Распределенные файловые системы
Обычно медиа-подсистемы характеризуются огромными объемами отдачи данных. Минус использования распределенных файловых систем в нашем случае в том, что Вы получаете огромный внутрисетевой трафик, и это выливается в малую эффективность при отдаче файлов. После ухода от GlusterFS на connect.ua наш исходящий медиа трафик вырос со 150 до 800 Мб/с.
Изоляция крупных и мелких файлов
Обязательно разносите мелкие и крупные файлы на разные физические хранилища (например, нужно разнести видео ролики и скриншоты к видео). Если они будут обслуживаться на одном сервере, то Ваша система будет медленнее черепахи. Это происходит потому, что чтение больших файлов не дает эффективно использовать дисковый кеш для мелких, и поэтому у Вас будет огромное количество рандомных чтений с диска. А это выльется в очень медленную отдачу файлов.
Cloud hosting
Сегодня большую популярность набирают cloud хостинги. Это решение имеет смысл, когда Вы планируете разработать и вывести прототипное решение.
Поскольку наращивание мощностей на таком хостинге экспоненциально влияет на его стоимость, то на определенном этапе следует делать выбор в сторону своей системы хранения. Но следует отметить, что cloud хостинги также обеспечивают высокую надежность и доступность (за что собственно и нужно платить), а это иногда немаловажный фактор.
Какие технологии Вы используете для обмена файлами между серверами? Используете ли распределенные файловые системы?


Если можно, пару вопросов:
1. Кроме Gluster что-нибудь еще пробовали, почему отказались ?
2. Всю работу по раскладыванию, реплицированию и обновлению медиа вы делали руками (PHP скриптом) ?
3. Мне кажется, та методология разброса файлов по серверам не даст вам выигрыша(Я исхожу из того, что диски у вас достаточно объемные): Большие файлы на 1м сервере будут слабо попадать в кеш из-за их размера, а мелкие на 2м сервере будут сильно вымывать кеш,в связи с их количеством. Здесь бы лучше было разбросать по степени “горячести” конетента, а не просто по размеру.
4. Если я правильно понял, вы пережимаете картинки и просто складываете их на m1, m2 и т.д. В таком случае у вас таки есть SPOF и RAID использовать всё же не помешало.
@point
1. Пробовали еще MogileFS - от нее отказалить изза проблем со стабильностью. От GlusterFS отказались изза проблем с производительностью
2. Да
3. Выигрышь дает огромный. Очень объемные диски - это как раз плохое решение, каждый сторадж - это небольшой узел. Дополнительное кеширование будет актуально только для сверх нагрузок - большие затраты на память.
4. Нет, на хранилищах хранятся только оригиналы картинок. Отдаются и пережимаются они на кеширующем сервере. Сервер этот один, планируем сделать fail over.
3. Т.е. у вас с десяток небольших серверов со средними по объему вениками и опять таки, небольшим количеством памяти ?
4. Если я правильно понял, на фронте nginx с ngx_http_image_filter_module ?
@point
3. Cейчас у нас три медиа сервера + два сервера транскодирования. Этого вполне хватает чтобы отдавать 1 ГБ/с в пики.
4. У нас собственная система преобразования картинок (на основе imagemagick), т.к. мы используем дополнительные механизмы, которых нет в ngx_http_image_filter_module
@Den Golotyuk
Спасибо за ответы! Очень интересно.
Как насчет использование Red Hat Global Files System http://www.redhat.com/gfs/ и создания централизованного файлового кластера?
Почему цифра при распределении файловый системы так силно изменилась?
@Андрей
Андрей, какая именно цифра?
@Maxim
Вся проблема как раз в создании “централизованного кластера”. В практике крупных систем необходимо уходить от всего централизованного (в адекватном приближении), т.к. это SPOF (http://en.wikipedia.org/wiki/Single_Point_of_Failure).
Если использовать GFS только в качестве транспорта, то это отличный выбор, однако убедитесь, что у Вас в строю есть администратор, способный настроить эту систему для эффективной работы.
Я так понимаю что вы в базе храните связку контента и сервера на котором он располагается?
@Ivan Shumkov
Да
Хм, накладно получается. Выгоднее хранить диапазоны ID контента: 1 - 1000000 = m1, 1000000 - 2000000 = m2
@Ivan Shumkov
1. Хранить таким образом не получиться, т.к. заранее будет неизвестно сколько места займет очередной диапазон объектов. Придется где-то хранить отрезки с соотв. маркерами серверов.
2. В этом случае запись будет происходить только на один (текущий) сервер, что при даже средних нагрузках сделает его практически недоступным для чтения.
Иван, позволь я немного дополню твой коммент:
на этот случай можно пробовать разбивать контент по последним цифрам ID:
0-4 - сервер 1
5-9 - сервер 2
на тот случай, если серверов стало не хватать добавляем 1 сервер, изменяем логику определения сервера и переливаем часть файлов по такой схеме:
0-3 - сервер 1
4-6 - сервер 2
7-9 - сервер 3
таким образом отвязываемся от базы и получаем довольно несложное масштабирование.
@tarasov
Интересная мысль, но перебалансировка видео/аудио файлов - это очень затратно (много файлов, большие размеры). При быстром росте придется делать часто, что плохо.