Рекомендуемая архитектура для обработки загрузки изображений пользователей


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

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

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

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

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

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

Author: Andy Baird, 2009-07-19

6 answers

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

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

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

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

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


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

 5
Author: David-SkyMesh, 2009-07-19 07:21:59

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

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

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

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

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

 2
Author: Aaron Fi, 2009-07-19 06:48:04

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

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

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

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

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

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

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

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

 1
Author: Alejandro Zuleta, 2009-07-19 09:52:47

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

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

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

 1
Author: djn, 2009-07-20 02:35:55

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

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

Гретц

Back2dos

 0
Author: back2dos, 2009-07-19 11:44:14

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

 0
Author: emix, 2014-01-08 19:00:53