Оптимальный способ хранения большого количества файлов

Как быть, если нужно хранить на сайте большое количество файлов изображений? Свалить их все в одну папку достаточно удобно с точки зрения программирования, но как это скажется на производительности? Следует ли переименовывать файлы, или оставлять как есть (учтите, что формат URL не поддерживает пробелы, а многие ОС не поддерживают кириллицу «из коробки»).

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

Ошибка номер 1: использование PHP и MySQL в качестве промежуточных механизмов для доступа к картинкам, css и прочим ресурсам.

Почему и как быть? => Доступ к изображению со стороны клиента должен быть прямым, чтобы не задействовать в этом PHP и тем более MySQL. Только прямой линк. Ведь картинок на странице может быть очень много, и если каждая картинка будет дёргать PHP, то вы получите очень нескучную нагрузку на систему и в итоге тормоза и зависания. Картинки и css должен отдавать только сервер как статические файлы. Напрямую.

Ошибка номер 2: хранить изображения со своими оригинальными именами. 

Почему и как быть? => Вы получите кучу геморроя при преобразовании имён файлов из кириллицы и других языков в латиницу. Системы на базе Linux очень плохо работают с кириллическими именами, кроме того, пробел в имени файла сыграет с вами злую шутку, поскольку пробелы в URL недопустимы. Совершенно незачем устраивать себе такой геморрой. Достаточно просто именовать все файлы через md5(оригинальное имя или ID). Имена в итоге будут такие: f789abc898d6892df98d09a8f8.jpg. Вполне нормальное уникальное имя для РЕСУРСА. А что до оригинальных имён файлов — можете просто хранить их в БД. Для доступа к ним со стороны клиента (браузера) оригинальные имена не нужны.

Ошибка номер 3: сваливать все изображения в одну папку.

Почему и как быть? => Некоторые операционные системы (и Linux тоже) начинают сильно тормозить при доступе в папку, в которой хранится 100 тысяч файлов и более. Идеально, если в каждой папке будет не больше 1000 файлов.

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

/ f7 / 89 / f789abc898d6892df98d09a8f8.jpg

Вы видите, что первый уровень подпапки повторяет первые 2 символа имени файла, а второй — следующие два символа. Количество уровней при желании можно увеличивать.

Это гарантирует количество подпапок в каждой папке не более 256 штук, и статистически количество файлов в каждой конечной подпапке будет делиться на 65 тысяч. То есть, при количестве файлов 1 миллион в каждой подпапке окажется по 10-20 файлов. Три уровня вложенности делят это количество на 16 миллионов, чего должно хватить для любых нужд.

Я сам лично напоролся на эту проблему, когда задумал автоматически сгенерированные превьюшки класть в одну общую папку (что-то вроде /cache/ или /thumbs/), но поскольку картинок было много, и к каждой картинке нужно было 5 разных превьюшек, то их количество очень быстро выросло до 200 тысяч и, как и написано выше, я поимел нешуточные тормоза. Так что учитесь на моей ошибке.

Успехов в программировании! Проектируйте приложения правильно!

Отправить ответ

Оставьте первый комментарий!

Notify of
avatar
wpDiscuz