Рекомендуемая архитектура для обработки загрузки пользовательских изображений - PullRequest
5 голосов
/ 19 июля 2009

Раньше я загружал изображения пользователей двумя разными способами:

  • Сохранить данные изображения в таблице базы данных и загрузить их с помощью PHP-скрипта
  • Загрузить изображение, преобразовать его в формат JPEG, поместить в каталог и загрузить с помощью тегов HTML

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

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

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

Какая ваша рекомендация в этой ситуации? Используете ли вы один из вариантов выше или у вас есть другое решение?

Ответы [ 6 ]

5 голосов
/ 19 июля 2009

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

Вы можете использовать гибридный подход.

Храните изображения в иерархии папок (согласно любой схеме, которую вы определили как подходящую для вашего приложения). Сохраните полный путь к каждому изображению в вашей базе данных.

В фоновом задании имейте эскизы полученных изображений (скажем, с помощью ImageMagick), имена файлов которых немного отличаются от самих изображений (например, добавьте «thumb-» на лицевой стороне), но которые хранятся рядом с реальными изображениями. У вас может быть поле в базе данных для каждого изображения, что означает «Мой эскиз готов, поэтому, пожалуйста, включите меня в галереи».

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


Edit: То, что говорит Аарон Ф., важно, когда вам нужно обработать очень большое количество запросов. Разделение данных изображения / sql - хороший путь к масштабируемости. Вам нужно будет посмотреть на шаблоны доступа в вашем приложении, чтобы определить, где находятся точки разделения. Еще раньше вы можете кэшировать сгенерированный HTML-код для галерей, чтобы уменьшить нагрузку на SQL.

2 голосов
/ 19 июля 2009

Два приведенных вами примера не проясняют самую важную часть: разбиение.

например. хранятся ли в базе данных изображения целиком в одной таблице на одном сервере базы данных? Или таблица разделена на несколько серверов / кластеров?

например. хранятся ли в каталоге все образы на одном жестком диске? Или образы отображаются на отдельные диски [RAID] на основе первой буквы в имени пользователя?

Для масштабируемости необходима хорошая схема разбиения.

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

1 голос
/ 20 июля 2009

Несколько лет назад я написал архив изображений в интрасети, предназначенный для хранения примерно 340 тысяч сканов плюс относительные миниатюры. Погуглив, я обнаружил, что нет веской причины не сбрасывать их все в один каталог, если вы не попросите базовую ОС составить список папок. Другими словами, вызов ls / dir может привести к зависанию машины, но простое извлечение отдельных файлов изображений по имени файла (из базы данных) не повлечет за собой снижения производительности.

Этот архив работает уже несколько лет, и я могу подтвердить, что он отлично работает с изображениями размером более 60 КБ, которые фактически хранятся в папке.

У меня никогда не было проблем с преобразованием файлов в jpeg с помощью GD, но для этой конкретной работы я использовал ImageMagick с MagicWand в качестве вспомогательного расширения (в основном из-за приличной документации).

1 голос
/ 19 июля 2009

Имхо, решение Дэвида является лучшим в большинстве случаев, но я бы изменил две детали:

Сохраните полный путь к каждому изображению в вашей базе данных.

Не думаю, что вам нужно хранить путь full , потому что если по какой-то причине каталог изображений изменится, это немного усложнит вашу жизнь. Хранения только имени файла должно быть достаточно. Вы всегда можете включить полный путь непосредственно в HTML.

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

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

Библиотека изображений PHP часто не справляется с конвертацией файла

Я предлагаю увеличить ограничение памяти в скрипте, в котором вы создаете большой палец, особенно если вы разрешаете загрузку больших (2 МБ +) файлов.

Вы можете сделать это с ini_set('memory_limit', '30M');. Конечно, фактическое количество зависит от вас. 30M работал для меня на сайтах с большим количеством эскизов.

0 голосов
/ 08 января 2014

Я бы использовал класс Thumbnailer , если вы спросите меня.

0 голосов
/ 19 июля 2009

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

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

Greetz

back2dos

...