загруженные файлы - база данных против файловой системы, при использовании Grails и MySQL - PullRequest
3 голосов
/ 29 января 2009

Я знаю, что это что-то вроде "классического вопроса", но разве mysql / grails (развернутый на Tomcat) по-новому взглянул на то, как подходить к хранению загруженных пользователем файлов.

Мне нравится использовать базу данных для всего (более простая архитектура, масштабирование - это просто масштабирование базы данных). Но использование файловой системы означает, что мы не загружаем mysql двоичными файлами. Некоторые могут также утверждать, что apache (httpd) быстрее, чем Tomcat, обслуживает двоичные файлы, хотя я видел цифры, которые показывают, что размещение Tomcat на передней панели вашего сайта может быть быстрее, чем использование прокси-сервера apache (httpd).

Как выбрать место для размещения загруженных файлов пользователя?

Спасибо за ваше внимание, время и мысли.

Ответы [ 4 ]

5 голосов
/ 29 января 2009

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

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

  • Бинарные файлы большого размера
  • Дорогие запросы

Преимущества

  • Атомные коммиты
  • Масштабирование идет с базой данных (хотя у MySQL есть некоторые проблемы с мультиузлом и т. Д.)
  • Менее сложный и сложный код для управления файловыми системами и т. Д.

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

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

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

В итоге мы создали решение для загрузки -> файловой системы. Для каждого загруженного файла была создана запись метаданных БД, которая управлялась в тандеме с процессом загрузки (и, наоборот, считывала эту запись при создании ссылки на контент GSP на изображение). Мы обслуживали запросы с диска через Apache напрямую на основании ссылки, запрашиваемой браузером. Но, и всегда есть, но помните, что с такими вещами, как файловые системы, у вас есть контент только на одну машину.

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

Другая проблема, с которой вы можете столкнуться при работе с файловыми системами, - это размер содержимого папки. Когда вы начинаете иметь папки, в которых буквально десятки тысяч файлов, сканирование папок на уровне операционной системы начинает по-настоящему тянуться. Чтобы избежать этой проблемы, нам пришлось написать код, который управлял загрузкой изображений в структуры папок yyyy / MM / dd / image.name.jpg, чтобы ни одна папка не накапливала сотни тысяч изображений.

Я имею в виду, что, хотя мы получили желаемую производительность, не используя БД для хранения больших двоичных объектов, это связано с затратами на разработку и управление системами.

3 голосов
/ 29 января 2009

В качестве дополнительного предложения: JCR (например, Jackrabbit ) - репозиторий содержимого Java. Он имеет несколько преимуществ, когда вы имеете дело с большим количеством двоичного контента. Плагин Grails еще не стабилен, но вы можете использовать Jackrabbit с простым API.

0 голосов
/ 01 декабря 2011

Даже если вы загружаете файл в файловую систему, все файлы получают одно и то же разрешение, поэтому любой зарегистрированный пользователь может получить доступ к файлу любого другого пользователя, просто введя URL-адрес (поскольку все они получают одинаковое разрешение). Однако если вы планируете предоставить каждому пользователю каталог, то ему предоставляется разрешение apache (то есть то, на что сервер имеет разрешение). Вы должны su, чтобы получить root, создать пользователя и загрузить файлы в эти каталоги. Снова доступ к этим файлам может привести к добавлению группы пользователей в группу серверов. Если я решу использовать файловую систему для хранения бинарных файлов, есть ли более простое решение, чем это, как вы управляете доступом к этим файлам, соответствующим каждому пользователю, и сохраняя разрешение? Помогает ли Spring ACL? Или мы должны создать группу разрешений для каждого пользователя? Я полностью крут с URL файловой системы. Моя единственная задача - запустить отдельный процесс (chmod и прочее), использовать что-то вроде ProcessBuilder для запуска команд операционных систем (или есть лучшее решение?). А как насчет разрешений?

0 голосов
/ 05 февраля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...