Как стать автором
Обновить

Комментарии 40

я бы по директориям раскладывал, иметь 80 тысяч файлов в одной папке, это нереальное извращение :)
+1 пускай попробует зайти потом в тут папку, чтоб удалить например пару картинок
rm /images/image.jpg?
о да, rm /images/IMG26_00012_блинкакойжетамбылутрехтысячнойфоткиномер.JPEG
Тоже люблю Воннегут, Стругацкие, поезд в теплый край, программирование, уфология :-)
А если например хранить аватарки 80000 пользователей, будет 80000 папок?
Такое не исключено…
тогда разделить по папкам по первой букве имени пользователя
или по хешу имени файла (хеш может быть любой, например первые 2 символа MD5)
Я бы советовал раскладывать по папкам, в каждую папку — фиксированное количество изображений. Распознавать из какой папки брать фотку — по ID-записи обявления, например так:

$folder = ceil($id / 500); // для случая, когда в каждой папке по 500 файлов.
как вариант аватарки хранить в базе в blob.
Оставляя тему скорости отдачи специалистам, скажу, что обязательно нужно думать о масштабируемости решения. Рано или поздно будет стоять вопрос о разнесении контента на разные сервера. Вот если оставите всё сейчас в одной куче — через 3-4 года, не ровен час, будете локти кусать :)
Тоже сначала про это подумал, но понял что локти кусать надо будет минут 10. А потом чётные налево, нечётные направо и всех дел то.

Хотя если сразу делить, то вообще делать ничего не придётся в этом плане, угу.
1) В целом — скорость зависит от файловой системы.
2) Оптимизируя, мне пришлось разделять файлы по папкам — 512 папок на 512 файлов. Было года 2 назад, я уже не помню, что именно у меня тормозило. Но факт, пришлось и сработало… файловая система была ext3.
Есть мнение что одному из них на самом деле лениво. А второй более адекватную вещь говорит — логическое размещение по папкам никому еще не мешало…
Согласен. Не просто так кеш Squid и eAccelerator'а разбиваются по папкам двойной вложености
В практике было, что при 50 000 файлов в одной директории на reiserfs сервер сервер начинает задумываться. Но, это если с этими файлами что-либо делать оптом, а если просто давать ссылки на индивидуальные файлы — таких проблем быть не должно.
При очень большом кол-ве файлов в одной директории при удаленном просмотре это будут километры траффика — это минус.
На некоторых файловых системах не будет срабатывать листинг директории с ОЧЕНЬ большим кол-вом файлов — будет вылетать с ошибкой (сталкивался на практике), так что лучше все же разносить :)
MediaWiki на всякий случай разносит в директории по первым буквам md5 и какой-то там соли.

upload.wikimedia.org/wikipedia/ru/b/bc/Wiki.png
В интернетах написано, что performance becomes terrible with above 10-15 thousand files, речь об Ext2 (Ext3).
В википедии про Ext2 сказано: If the number of files in a directory exceeds 10000 to 15000 files, the user will normally be warned that operations can last for a long time unless directory indexing is enabled.

Получается, что прав первый, если речь об Ext2(3), по поводу других файловых систем лучше проконсультрироваться отдельно.
раскидывайте по директориям, у меня на серваке под фряхой один раз в одной директории скопилось много файлов, так в директорию было не зайти, на команду ls выдавалось сообщение, что список слишком большой, пришлось перекидывать файлы по папкам. bash мне помог в этом =)
1-й программист прав.
2-й слышал, что бывают *nix-системы. Если бы он аргументированно смог рассказать как хранится информация о файлах в той или иной FS, как производится выборка, какова сложность этой выборки, и почему она «зависит/не зависит» от типа дискового хранилища, можно было бы порассуждать. Но лучше выбрать первый вариант и стать независимым от этих вопросов.
Лучше разбивать — храните файл с именем abcd123.jpg в папке a/b/c/d/abcd123.jpg
С точки зрения масштабирования — по директориям
Тогда будет легко директории разносить по серверам и мапить их внутри логики
Раскладывать необходимо. Не раскладывать можно исключительно в больших FSS.
Через несколько лет число файлов выйдет на уровень 130 тысяч, и хочешь-не хочешь, а разделять придется.

У нас в проекте, например, аватарка пользователя номер 156301 будет храниться в /images/3/15/63/01/avatar.jpg… при этом глубина такой структуры будет возрастать в логарифмической последовательности (то есть при увеличении числа пользователей в 100 раз глубина увеличится на 1, а при увеличении в 10000 раз, на 2)

Да и зачем насиловать файловую систему, если можно этого не делать?
Если названия вы задаете сами, то обычно такие данные хранятся в «матрице» n x n, упорядочено по имени файла.
Произвольно генерируем название с 4-мя цифрами в начале/конце, кладем в директорию вида /images/03/43/, где 0343 — как раз те числа. Таким образом получается более-менее равномерно размазанная по ФС структура. При суммарно 80к картинок, в одной директории будет лежать 8 файлов.
Разбивать нужно, но разбивать с умом. Если у вы будете разносить все файлы по признаку первой буквы пользователей, или айдишнику фотки в базе — ничего хорошего не выйдет. Судите сами: Вы разнесете файлы по 20 папкам, на странице будет 50 объектов разделенных по какому-то случайному признаку. Скорее всего серверу придется обратится во все 20 папок, по скорости вы не выиграете ни сколько, скорее даже проиграете. Нужно подумать, как сделать так, чтобы на одной странице всегда были фотки из нескольких (в идеале одной) папки. Если, например, фотографии показываются в хронологическом порядке, хорошим решением будет класть по 500 штук в папку (как было предложено void_1977 ранее). Если по разделам, лучше и сделать для каждого раздела свою папку.
У меня практически везде реализовано так: исходники аватарок, которые заливают пользователи, хранятся в папке users/имя_юзера/avatar_текущий_таймстамп.jpg (при этом название картинки привязывается в базе к юзеру). Когда запрашивается аватарка, она запрашивается не на прямую, а через скрипт, который уменьшает исходную картинку до нужных размеров и по совместительству еще кэширует ее в папку cache/users/хэш_путь_до_исходной_картинки.jpg. Тоесть фактически после первого запроса все картинки лежат в одной папке, но их исходники лежат в разных (это еще в разы уменьшает размер бэкапа, так как бэкапятся только исходные картинки).

Основной минус в том, что в кэше остаются неиспользуемые картинки. Но сейчас место дешевое :)
Посмотрите на структуру директорий, которой пользуются файлохранилища и хостинги картинок — у них эти технологии отработаны.
Некоторые пользуются даже своими файловыми системами, например google

Вообще хранение файлов (дисковая, файловая система) — это очень узкое место.
А я ложу по папкам так…
например
имя файла: avatar.jpg

создаю папки по первым трем буквам (можно 4-м)
получаем

/a/v/a/avatar.jpg

Далее, если только аватарки, то можно по дате
/2009/05/30/avatar_1.jpg

оба варианта довольно неплохие

а если в папке меньше трех символов?
ну и что что 80 тыс, у меня в винде папка ~TRASH имеет ~460к файлов и около 40к папок (суммарный размер около 480 гиг)… и ничего, не умирает...как я понимаю у автора есть вполне нормальный и адекватный вариант — разбивать по дням создания объявления (аля 20090530\объявление_id_filename.jpg). Имхо это было бы удобно с т.з. архивирования старых объявлений, бэкапирования и т.д.
Если раскладывать то по первым символам md5 хэша. Тогда количество фаилов в папке будет примерно одинаковое. Даже 2х уровней вложенности вам хватит abfff1121 -> /a/b/abfff1121
Аналогично сделано на sourceforge: /home/u/us/username/…
Можно разбивать по датам
-год
--месяц
-----день — image1
— image2…
по опыту, при сохранении файлов в одной директории, возрастают накладные расходы операционной системы. мы хранили файлы, раскладывая их по папкам полученным мд5 от имени фалов, те что-то типа 3f/4a/34/filename.ext.
сервер стал работать шустрее )
получается 256*256*256 = 166777216 директорий, на первое время хватит, причем файлы будут равномерно распределяться по этим директориям, в отличии от хранения по алфавиту и дате
Есть ограничение на количество файлов передаваемых операции по маске (rm -f ./file*). Количество честно говоря не помню, но порядок тот что указал автор.
У меня IP-камеры наблюдения складывают картинки в RAID на UFS (FreeBSD), потом эти картинки доступны через WEB. Вначале я ничего не делал, но когда кол-во файлов превысило ~ 100 тыс в папке, стало заметно тормозить (именно WEB, Apache). В смысле, веб сервер выдавал картинку с секундной и более задержкой.

Тогда разложил в папки по камерами и по датам (внутри папок с камерами). Структура директорий — «камера/год.месяц/день/». Тогда в папке получается примерно 2-4 тыс кадров, да и иерархия удобная.

Тогда же, я опытным путём выяснил, что при 30 тыс файлов и более, веб-сервер уже начинает тормозить. Заметим, что при этом, какой-нить Fast Stone Image Viewer тормозит при начальной загрузке через Samba-FS уже при 5 тыс. картинок.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории