Задать вопрос

Распределенное хранилище изображений

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

Мы пришли к следующей схеме: есть физическая машина, являющаяся точкой входа, и N дополнительных хранилищ. На главном сервере установлены nginx, слушающий 80 порт и apache. При обращении к серверу nginx ищет обработанное изображение в файловой системе, если не находит, пытается найти изображение на дополнительных серверах. Если изображения нет и там, через apache nginx обращается к PHP скрипту, который ищет исходник нужного изображения на машинах (загружатся изображение может напрямую на любую из машин), выполняет необходимые обработки и сохраняет обработанные изображения в хранилище. Если же не найден оригинал изображения, php отдает 404-е заголовки, в ответ на которые nginx отдает картинку-заглушку.

Прошу советов по самой схеме работы (возможно, есть альтернативные варианты построения взаимодействия, которые нам подойдут?), а так же помощи с конфигурированием nginx (конкретно — не получается обработать возвращаемые apache заголовки в nginx через error_page).

Всем заранее спасибо!
  • Вопрос задан
  • 4631 просмотр
Подписаться 5 Оценить 1 комментарий
Пригласить эксперта
Ответы на вопрос 5
Anonym
@Anonym
Программирую немного )
Не совсем понятно, почему «исходные картинки могут храниться на любом из серверов».
Логично было бы сделать такую архитектуру, при которой по имени изображения можно однозначно определить ее местоположение.
1. В момент загрузки картинки определять сервер, на котором она должна храниться.
2. Именовать картинку соответственно хранилищу.
3. При отдаче вы точно знаете, где ее искать.
Ответ написан
Комментировать
AxisPod
@AxisPod
Имхо будет совсем не быстро. Ну локально файл проверить не долго, а вот проверить на других N серверах будет уже и не быстро. И опять же узким местом может оказаться канал до балансировщика (точки входа).

Я бы посоветовал рассмотреть вариант, когда на этапе генерации html контента уже известно месторасположение картинок. Каждый сервер имеет своё поддомен, например: img1.domain.com, img2.domain.com и т.д. Здесь вы так же сможете легко накинуть dns балансировку.

Ну и соответственно, если нет готовой картинки, уже отдаёте путь до пхп скрипта.

Хранить id хранилища рядом с нужной версией картинки будет не сложно.
Ответ написан
Комментировать
К главной машине через NFS подключены N с превюшками.
Через NFS легко проверяем на каком из серверов есть уже обработанное изображение и редиректим на него.
Изначально через NFS планировалось только проверять наличие файла, но после долгих тестов оказалось что даже с записью превюшек на другие сервера он справляется на ура. Падает не чаще раз в год.
Ответ написан
Комментировать
difiso
@difiso
В параллельной вселенной я космонавт
А почему не сделать простую БД на точке входа, в которой будет храниться путь до картинки (или хотябы имя сервера)? Поиск все равно будет производиться, но на правильно сделаной базе искать придется намного меньше, и работать будет намного быстрее.
Ответ написан
@rozhik
Я хочу предложить следующий вариант.

Идея:
0 опционально — поиск на локальной ФС
1 создаётся хэш-функция от пути к картинке, возвращающая целое число. hashVal
2. выбирается фронт сервер с номером hashVal % serversCount, и если он живой — стягивается картинка с этого сервера. если её нет — то генерится.
3. если сервер не живой — берем следующий.и переходим к пункту 2.

На практике такое решение ущербно по причине того, что после выхода из строя сервера — следующий сервер становится перегружен.
В живом проэкте используется модификация:
Есть 1000 записей в мэмкеше. Инициированых значениями из пункта 2. После падения фронт сервера его индексы меняются на индексы живых серверов случайным образом. После поднятия — восстанавливаются.
(на самом деле чуть сложнее, так как каждая картинка живет всегда на 3х серверах, и доступ к ним балансируется каруселью, но это не важно для этого вопроса)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы