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

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

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

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

Всем заранее спасибо!
  • Вопрос задан
  • 4621 просмотр
Пригласить эксперта
Ответы на вопрос 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х серверах, и доступ к ним балансируется каруселью, но это не важно для этого вопроса)
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽
26 апр. 2024, в 18:27
200000 руб./за проект
26 апр. 2024, в 18:24
80000 руб./за проект
26 апр. 2024, в 18:00
500 руб./за проект