Советы по управлению большим количеством файлов?
-
21-08-2019 - |
Вопрос
Здесь, на SO, есть несколько очень хороших вопросов об управлении файлами и их хранении в рамках большого проекта.
Хранение изображений в базе данных - Да или Нет?
Будете ли вы хранить двоичные данные в базе данных или в файловой системе?
У первого есть несколько замечательных идей, и в своем проекте я решил пойти по файловому маршруту, а не по маршруту базы данных.
Основным аргументом против использования файловой системы является резервное копирование.Но в нашей системе у нас есть отличная схема резервного копирования, так что я не беспокоюсь по этому поводу.
Следующий путь - это способ хранения самих файлов.И я подумал о том, чтобы всегда сохранять местоположение файлов статичным и создать виртуальную систему каталогов на стороне базы данных.Таким образом, ссылки на файл не меняются.
Система, которую я создаю, будет иметь единое глобальное управление файлами, поэтому все файлы будут доступны всем пользователям.Но многие, кто прошел по файловому маршруту, говорят о физическом размере каталога (например, если все файлы находятся в одном каталоге).
Итак, мой вопрос в том, каковы некоторые советы или наилучшие практические методы по созданию папок для этих статических файлов, или мне вообще не следует использовать маршрут виртуального каталога.
(проект находится в стеке LAMP (PHP), если это вообще поможет)
Решение
Один из способов - присвоить каждому файлу уникальный номер и использовать его для поиска фактического местоположения файла.Затем вы можете использовать это число для распространения файлов по разным каталогам файловой системы.Например, вы могли бы использовать что-то вроде этой схемы:
/images/{0}/{1}/{2}
{0}: file_number % 100
{1}: (file_number / 100) % 100
{2}: file_number
Другие советы
Некоторое время назад я столкнулся с этой проблемой для веб-сайта, на котором размещалось много файлов.Что мы сделали, так это взяли GUID (который также является полем первичного ключа файла) (напримерBCC46E3F-2F7A-42b1-92CE-DBD6EC6D6301) и сохранить файл, подобный этому:/B/C/C/BCC46E3F-2F7A-42b1-92CE-DBD6EC6D6301/имя файла.ext
Это имеет определенные преимущества:
- Вы можете масштабировать файловые серверы на нескольких серверах (и назначить каждому из них определенные каталоги).
- Вам не нужно переименовывать файл
- Ваши каталоги гарантированно будут уникальными
Надеюсь, это поможет!
Чтобы избежать создания чрезмерного количества записей в одном каталоге, вы можете захотеть основывать создание каталогов на фрагментах имени файла.Так, например, если у вас есть файл с именем d7f5ae9b7c5a.png, вы можете захотеть сохранить его в файле media/d7/ f5/d7f5ae9b7c5a.png.Если все ваши имена файлов шестнадцатеричные, то это ограничит количество записей в одном каталоге 256 вплоть до конечного уровня.
Один из пупков ~ 100kb, так что есть 10 000 пользователей в базе данных, каждый пользователь будет иметь в среднем 5 изображений, так что мы будем иметь 5 терабайт DB, и каждый вывод изображения будет выполняться с помощью БД и это дополнительный трафик DB уменьшит общий сервер Perfomance DB. ... Вы можете использовать кластер БД, чтобы избежать этого, но предположим, что это дорого
Отчет пользователя об ошибке на живой базе данных (на тест - все работает правильно), как бы вы создать дамп распаковать его на разработчиков машины? Сколько времени это займет?
В один момент вы можете решить поместить изображения на некоторых CDN, каковы будут изменения в исходном коде?
Обычно я придерживаюсь такого подхода:
Создайте глобальную переменную настроек для вашего приложения, которая указывает на папку, в которой вы храните загруженные файлы.В вашей базе данных хранятся относительные пути к файлам (относительно того, на что указывает переменная настроек).
Таким образом, если файл расположен по адресу /www/uploads/image.jpg, переменная ваших настроек указывает на /www/загружает строку вашей базы данных image.jpg.Это гибкий способ, который отделяет структуру системных каталогов от вашего приложения.
Кроме того, вы можете фрагментировать файловое хранилище по каталогам в зависимости от того, к каким таблицам базы данных они относятся.Допустим, у вас есть таблица user_reports и таблица user_photos.Файлы, относящиеся к user_reports, хранятся в /www/uploads/user_reports.Если у вас большое количество пользовательских загрузок, вы можете реализовать fragmentaion еще дальше.Допустим, пользователь загружает файл 20.03.2009, файл называется report.pdf, поэтому вы сохраняете его по адресу /www/uploads/user_reports/2009/03/20/ report.pdf.
Я не могу много сказать о том, как apache и PHP управляют файлами, но я могу кое-что сказать о файловой системе ext3.у ext3, похоже, нет проблем с большим количеством файлов в одном каталоге.Я протестировал его примерно на миллионе файлов.Убедитесь, что опция dir_index включена в файловой системе, прежде чем создавать каталоги.Вы можете проверить, запустив dump2fs, и изменить этот параметр, запустив tune2fs.Хэширование файлов в дерево подкаталогов все еще может быть полезным, поскольку у инструментов командной строки все еще могут возникнуть проблемы со списком содержимого каталога.