Советы по управлению большим количеством файлов? - PullRequest
13 голосов
/ 22 марта 2009

В SO есть несколько очень хороших вопросов об управлении файлами и их хранении в большом проекте.

Хранение изображений в БД - да или нет?
Будете ли вы хранить двоичные данные в базе данных или в файловой системе?

Первый из них имел отличные идеи, и в своем проекте я решил пойти по пути файла, а не по маршруту БД.

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

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

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

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

(проект находится в стеке LAMP (PHP), если это вообще помогает)

Ответы [ 6 ]

12 голосов
/ 22 марта 2009

Один из способов - присвоить уникальный номер каждому файлу и использовать его для поиска фактического местоположения файла. Затем вы используете это число для распространения файлов в разных каталогах файловой системы. Например, вы можете использовать что-то вроде этой схемы:

/images/{0}/{1}/{2}

{0}: file_number % 100
{1}: (file_number / 100) % 100
{2}: file_number

9 голосов
/ 22 марта 2009

Я столкнулся с этой проблемой некоторое время назад для веб-сайта, на котором размещалось много файлов. Мы взяли GUID (который также является полем первичного ключа файла) (например, BCC46E3F-2F7A-42b1-92CE-DBD6EC6D6301) и сохранили файл, подобный следующему: / B / C / C / BCC46E3F-2F7A-42b1 -92CE-DBD6EC6D6301 / filename.ext

Это имеет определенные преимущества:

  • Вы можете масштабировать файловые серверы на нескольких серверах (и назначать каждому из них определенные каталоги)
  • Вам не нужно переименовывать файл
  • Ваши каталоги гарантированно будут уникальными

Надеюсь, это поможет!

6 голосов
/ 22 марта 2009

Чтобы избежать создания чрезмерного количества записей в одном каталоге, вы можете основывать создание каталогов на фрагментах имени файла. Например, если у вас есть файл с именем d7f5ae9b7c5a.png, вы можете захотеть сохранить его в media / d7 / f5 / d7f5ae9b7c5a.png. Если все ваши имена файлов шестнадцатеричные, это ограничит количество записей в одном каталоге до 256 вплоть до последнего уровня.

2 голосов
/ 22 марта 2009
  1. Одно изображение пользователя ~ 100 КБ, поэтому пусть в базе данных будет 10 000 пользователей, у каждого пользователя будет в среднем 5 изображений, поэтому у нас будет 5 ТБ данных, и каждый вывод изображения будет выполняться через БД и дополнительный трафик БД снизит общую производительность сервера БД. ... вы можете использовать кластер БД, чтобы избежать этого, но предположим, что это дорого

  2. Пользовательский отчет об ошибке в действующей базе данных (в тесте - все работает правильно), как бы вы создали дамп и распаковали его на машине разработчика? Сколько времени это займет?

  3. В один момент вы можете решить поместить изображения в какой-нибудь CDN, каковы будут изменения в вашем исходном коде?

1 голос
/ 22 марта 2009

Я не могу сказать много о том, как apache и PHP управляют файлами, но я могу кое-что сказать о файловой системе ext3. У ext3, похоже, нет проблем с большим количеством файлов в одном каталоге. Я проверил до миллиона файлов. Убедитесь, что в файловой системе включена опция dir_index, прежде чем создавать каталоги. Вы можете проверить, запустив dump2fs и изменить эту опцию, запустив tune2fs. Хэширование файлов в дереве подкаталогов все еще может быть полезно, потому что у инструментов командной строки все еще могут быть проблемы с перечислением содержимого каталога.

1 голос
/ 22 марта 2009

Я обычно придерживаюсь этого подхода:

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

Так что, если файл находится по адресу /www/uploads/image.jpg, переменная ваших настроек указывает на / www / uploads строку вашей базы данных с image.jpg. Это гибкий способ, позволяющий отделить структуру каталогов вашей системы от вашего приложения.

Далее вы можете фрагментировать файловое хранилище в каталогах в зависимости от того, к каким таблицам базы данных они относятся. Скажем, у вас есть таблица user_reports и таблица user_photos. Вы храните файлы, относящиеся к user_reports, в / www / uploads / user_reports. Если у вас есть большое количество пользовательских загрузок, вы можете реализовать фрагментацию еще дальше. Скажем, пользователь загружает файл 20.03.2009, файл называется report.pdf, поэтому вы храните его по адресу /www/uploads/user_reports/2009/03/20/report.pdf.

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