Сколько файлов можно поместить в каталог?
=========================================

Неважно, сколько файлов я храню в одном каталоге? Если да, то сколько файлов в каталоге слишком много, и каковы последствия наличия слишком большого количества файлов? (Это на сервере Linux.)

Справочная информация. У меня есть сайт фотоальбома, и каждое загруженное изображение переименовывается в 8-значный символ (скажем, a58f375c.jpg). Это делается для того, чтобы избежать конфликтов имен файлов (например, загружено много файлов "IMG0001.JPG" ). Исходное имя файла и любые полезные метаданные хранятся в базе данных. Прямо сейчас у меня в каталоге изображений около 1500 файлов. Это делает список файлов в каталоге (через FTP или SSH-клиент) занимать несколько секунд. Но я не вижу, что это имеет какой-то эффект, кроме этого. В частности, нет никакого влияния на то, как быстро файл изображения обслуживается пользователем.

Я подумал о сокращении числа изображений, выполнив 16 подкаталогов: 0-9 и a-f. Затем я переместил изображения в подкаталоги на основе первой шестнадцатеричной цифры имени файла. Но я не уверен, что есть какие-то причины для этого, за исключением случайного перечисления каталога через FTP/SSH.

 

 [FAT32](http://en.wikipedia.org/wiki/File_Allocation_Table#FAT32%23FAT32):
===========================================================================

 * Максимальное количество файлов: 268 173 300
* Максимальное количество файлов в каталоге: 2 16 - 1 (65 535)
* Максимальный размер файла: 2 ГиБ - 1 без [LFS](http://en.wikipedia.org/wiki/Large_file_support), 4 ГиБ - 1 с

 [NTFS](http://en.wikipedia.org/wiki/NTFS):
===========================================

 * Максимальное количество файлов: 2 32 - 1 (4 294 967 295)
* Максимальный размер файла
	+ Реализация: 2 44 - 2 6 байтов (16 TiB - 64 KiB)
	+ Теоретический: 2 64 - 2 6 байтов (16 EiB - 64 КиБ)
* Максимальный размер тома
	+ Реализация: 2 32 - 1 кластер (256 ТиБ - 64 КиБ)
	+ Теоретически: 2 64 - 1 кластера (1 Yi - 64 КиБ)

 [ext2](http://en.wikipedia.org/wiki/Ext2):
===========================================

 .i1a { width: 336px; height: 280px; }
 @media(min-width: 768px) { .i1a { width: 728px; height: 90px; } }
 @media(min-width: 992px) { .i1a { width: 360px; height: 300px; } }
 @media(min-width: 1083px) { .i1a { width: 728px; height: 90px; } }

 (adsbygoogle = window.adsbygoogle || []).push({});

* Максимальное количество файлов: 10 18
* Максимальное количество файлов в каталоге: ~ 1,3 × 10 20 (проблемы с производительностью после 10 000)
* Максимальный размер файла
	+ 16 ГиБ (размер блока 1 КиБ)
	+ 256 ГиБ (размер блока 2 КиБ)
	+ 2 TiB (размер блока 4 КиБ)
	+ 2 TiB (размер блока 8 КиБ)
* Максимальный размер тома
	+ 4 TiB (размер блока 1 КиБ)
	+ 8 ТиБ (размер блока 2 КиБ)
	+ 16 TiB (размер блока 4 КиБ)
	+ 32 ТиБ (размер блока 8 КиБ)

 [ext3](http://en.wikipedia.org/wiki/Ext3):
===========================================

 * Максимальное количество файлов: min (volumeSize/2 13 numberOfBlocks)
* Максимальный размер файла: такой же, как у ext2
* Максимальный размер тома: такой же, как у ext2

 [ext4](http://en.wikipedia.org/wiki/Ext4):
===========================================

 * Максимальное количество файлов: 2 32 - 1 (4 294 967 295)
* Максимальное количество файлов в каталоге: не ограничено
* Максимальный размер файла: 2 44 - 1 байт (16 ТиБ - 1)
* Максимальный размер тома: 2 48 - 1 байт (256 ТиБ - 1)

 

У меня было более 8 миллионов файлов в одном каталоге ext3. libc `readdir()`, который используется `find`, `ls` и большинство других методов, обсуждаемых в этом потоке, для отображения больших каталогов.

В этом случае причина `ls` и `find` невелика, так как `readdir()` считывает только 32 Кбайта записей каталога, поэтому на медленных дисках потребуется много разных чтений для списка каталогов. Существует решение этой проблемы скорости. Я написал довольно подробную статью об этом: <http://www.olark.com/spw/2011/08/you-can-list-a-directory-with-8-million-files-but-not-with-ls/>

 .i2a { width: 336px; height: 280px; }
 @media(min-width: 768px) { .i2a { width: 728px; height: 90px; } }
 @media(min-width: 992px) { .i2a { width: 360px; height: 300px; } }
 @media(min-width: 1083px) { .i2a { width: 728px; height: 90px; } }

 (adsbygoogle = window.adsbygoogle || []).push({});

Отключить ключ: использовать `getdents()` напрямую - <http://www.kernel.org/doc/man-pages/online/pages/man2/getdents.2.html>, а не что-либо, основанное на libc `readdir()`, чтобы вы может указывать размер буфера при чтении записей каталога с диска.

 

Это зависит от конкретной файловой системы, используемой на сервере Linux. В настоящее время по умолчанию используется ext3 с dir\_index, что значительно ускоряет поиск больших каталогов.

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

Существует ограничение на общее количество файлов в одном каталоге. Кажется, я помню, что он определенно работал до 32000 файлов.

 

У меня есть каталог с 88,914 файлами. Как и вы, это используется для хранения миниатюр и на сервере Linux.

Перечисленные файлы по FTP или php-функции медленны, но есть и производительность при отображении файла. например www.website.com/thumbdir/gh3hg4h2b4h234b3h2.jpg имеет время ожидания 200-400 мс. В сравнении с другим сайтом, у меня есть около 100 файлов в каталоге, изображение отображается после всего ~ 40 мс ожидания.

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

 

Имейте в виду, что в Linux, если у вас есть каталог со слишком большим количеством файлов, оболочка, возможно, не сможет расширять подстановочные знаки. У меня есть эта проблема с фотоальбомом, размещенным на Linux. Он сохраняет все измененные изображения в одном каталоге. Хотя файловая система может обрабатывать много файлов, оболочка не может. Пример:

```
-shell-3.00$ ls A
-shell: /bin/ls: Argument list too long

или

-shell-3.00$ chmod 644 *jpg
-shell: /bin/chmod: Argument list too long

```
 

Я работаю над подобной проблемой прямо сейчас. Мы имеем иерархическую структуру каталогов и используем идентификаторы изображений в качестве имен файлов. Например, изображение с `id=1234567` помещается в

```
..../45/67/1234567_<...>.jpg

```

используя последние 4 цифры, чтобы определить, куда идет файл.

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

 

Для чего это стоит, я просто создал каталог в файловой системе `ext4` с 1 000 000 файлов в нем, а затем случайно получил доступ к этим файлам через веб-сервер. Я не заметил никакой премии за доступ к тем, кто (скажем) имел только 10 файлов.

Это радикально отличается от моего опыта, сделанного на `ntfs` несколько лет назад.

 

Самая большая проблема, с которой я столкнулся, - это 32-битная система. Когда вы передаете определенное число, инструменты, такие как "ls", перестают работать.

Попытка сделать что-либо с этим каталогом, как только вы пройдете, этот барьер станет огромной проблемой.

 

Это действительно зависит от используемой файловой системы, а также от некоторых флагов.

Например, [ext3](http://en.wikipedia.org/wiki/Ext3) может иметь много тысяч файлов; но после нескольких тысяч, это было очень медленно. В основном при перечислении каталога, но также при открытии одного файла. Несколько лет назад он получил опцию "htree", которая значительно сократила время, необходимое для получения индексного дескриптора с именем файла.

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

 

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

Даже если файловая система делает это правильно, все же абсолютно возможно, чтобы программы, которые отображали содержимое каталога, испортились и выполняли сортировку O (n ^ 2), поэтому, чтобы быть в безопасности, я всегда ограничивал число файлов в каталоге не более 500.

 

Вопрос сводится к тому, что вы собираетесь делать с файлами.

В Windows любая директория с файлами размером более 2 тыс. медленно меняет в Explorer. Если все файлы изображений, более 1 тыс. Имеют тенденцию открываться очень медленно в виде эскизов.

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

 

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

В качестве примера F-Spot хранит файлы фотографий как YYYY\MM\DD\filename.ext, что означает самый большой каталог, с которым мне приходилось иметь дело, при ручном манипулировании моей коллекцией ~ 20000-фотографий около 800 файлов. Это также упрощает просмотр файлов с стороннего приложения. Никогда не предполагайте, что ваше программное обеспечение - единственное, что будет доступно для ваших файлов программного обеспечения.

 

ext3 действительно имеет ограничения размера каталога, и они зависят от размера блока файловой системы. В каждом каталоге "максимальное количество" файлов не указано "максимальное количество", а для каждого каталога "максимальное количество блоков, используемых для хранения записей файла". В частности, размер самого каталога не может превышать b-дерево высотой 3, а разветвление дерева зависит от размера блока. См. Эту ссылку для некоторых деталей.

 <https://www.mail-archive.com/cwelug@googlegroups.com/msg01944.html>

Я недавно был укушен в файловую систему, отформатированную с помощью блоков 2K, которая необъяснимо получала сообщения с полным содержимым ядра `warning: ext3_dx_add_entry: Directory index full!` при копировании с другой файловой системы ext3. В моем случае каталог с 480 000 файлов не был скопирован в пункт назначения.

 

Я помню, как запускал программу, которая создавала огромное количество файлов на выходе. Файлы были отсортированы по 30000 за каталог. Я не помню проблем с чтением, когда мне приходилось повторно использовать произведенную продукцию. Это было на 32-разрядном ноутбуке Ubuntu Linux, и даже [Nautilus](http://en.wikipedia.org/wiki/GNOME_Files) отображал содержимое каталога, хотя и через несколько секунд.

ext3 файловая система: аналогичный код в 64-битной системе хорошо справился с 64000 файлами в каталоге.

 

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

 

У меня возникла аналогичная проблема. Я пытался получить доступ к каталогу с более чем 10 000 файлов. Слишком много времени для создания списка файлов и запуска любых команд в любом из файлов.

Я придумал немного php script, чтобы сделать это для себя и попытался понять, как предотвратить его от времени в браузере.

Ниже приведен php script, который я написал для решения проблемы.

 [Список файлов в каталоге со слишком большим количеством файлов для FTP](http://www.swhistlesoft.com/blog/2010/11/18/42-listing-files-in-a-directory-with-too-many-files-for-ftp)

Как это помогает кому-то

 

Я предпочитаю то же самое, что [@armandino](/questions/15119/how-many-files-can-i-put-in-a-directory/110139#110139). Для этого я использую эту небольшую функцию в PHP для преобразования идентификаторов в путь к файлу, который приводит к 1000 файлам в каталоге:

```
function dynamic_path($int) {
    // 1000 = 1000 files per dir
    // 10000 = 10000 files per dir
    // 2 = 100 dirs per dir
    // 3 = 1000 dirs per dir
    return implode('/', str_split(intval($int / 1000), 2)) . '/';
}

```

 или вы можете использовать вторую версию, если хотите использовать буквенно-цифровой:

```
function dynamic_path2($str) {
    // 26 alpha + 10 num + 3 special chars (._-) = 39 combinations
    // -1 = 39^2 = 1521 files per dir
    // -2 = 39^3 = 59319 files per dir (if every combination exists)
    $left = substr($str, 0, -1);
    return implode('/', str_split($left ? $left : $str[0], 2)) . '/';
}

```

результаты:

```
<?php
$files = explode(',', '1.jpg,12.jpg,123.jpg,999.jpg,1000.jpg,1234.jpg,1999.jpg,2000.jpg,12345.jpg,123456.jpg,1234567.jpg,12345678.jpg,123456789.jpg');
foreach ($files as $file) {
    echo dynamic_path(basename($file, '.jpg')) . $file . PHP_EOL;
}
?>

1/1.jpg
1/12.jpg
1/123.jpg
1/999.jpg
1/1000.jpg
2/1234.jpg
2/1999.jpg
2/2000.jpg
13/12345.jpg
12/4/123456.jpg
12/35/1234567.jpg
12/34/6/12345678.jpg
12/34/57/123456789.jpg

<?php
$files = array_merge($files, explode(',', 'a.jpg,b.jpg,ab.jpg,abc.jpg,ddd.jpg,af_ff.jpg,abcd.jpg,akkk.jpg,bf.ff.jpg,abc-de.jpg,abcdef.jpg,abcdefg.jpg,abcdefgh.jpg,abcdefghi.jpg'));
foreach ($files as $file) {
    echo dynamic_path2(basename($file, '.jpg')) . $file . PHP_EOL;
}
?>

1/1.jpg
1/12.jpg
12/123.jpg
99/999.jpg
10/0/1000.jpg
12/3/1234.jpg
19/9/1999.jpg
20/0/2000.jpg
12/34/12345.jpg
12/34/5/123456.jpg
12/34/56/1234567.jpg
12/34/56/7/12345678.jpg
12/34/56/78/123456789.jpg
a/a.jpg
b/b.jpg
a/ab.jpg
ab/abc.jpg
dd/ddd.jpg
af/_f/af_ff.jpg
ab/c/abcd.jpg
ak/k/akkk.jpg
bf/.f/bf.ff.jpg
ab/c-/d/abc-de.jpg
ab/cd/e/abcdef.jpg
ab/cd/ef/abcdefg.jpg
ab/cd/ef/g/abcdefgh.jpg
ab/cd/ef/gh/abcdefghi.jpg

Как вы можете видеть для $int` -version, каждая папка содержит до 1000 файлов и до 99 каталогов, содержащих 1000 файлов и 99 каталогов...

Но не забывайте, что для многих каталогов можно ускорить процесс резервного копирования. Не стесняйтесь тестировать от 1000 до 10000 файлов в каталоге, но не добавляйте их гораздо больше, так как у вас будет очень длительное время доступа, если вы хотите прочитать файл каталога по файлу (ftp-клиенты, функции чтения файлов и т.д.).

Наконец, вы должны подумать о том, как уменьшить количество файлов в целом. В зависимости от вашей цели вы можете использовать спрайты CSS для объединения нескольких крошечных изображений, таких как аватары, значки, смайлики и т.д., Или если вы используете множество небольших не-медиафайлов, подумайте о их объединении, например. в формате JSON. В моем случае у меня было тысячи мини-кешей, и, наконец, я решил объединить их в пакеты по 10.

 

Большинство ответов, приведенных выше, не показывают, что нет ответа "Один размер подходит всем" на исходный вопрос.

В сегодняшней среде у нас есть большой конгломерат различного оборудования и программного обеспечения - некоторые из них - 32 бит, а некоторые - 64 бит, некоторые из них режут и некоторые из них проверены и верны - надежны и никогда не меняются.
К этому добавляется множество старых и новых аппаратных средств, более старых и новых ОС, разных поставщиков (Windows, Unix, Apple и т.д.) И множество утилит и серверов, которые идут вместе.
Поскольку аппаратное обеспечение улучшилось, а программное обеспечение преобразовано в 64-битную совместимость, неизбежно возникла значительная задержка с тем, чтобы все части этого очень большого и сложного мира играли хорошо с быстрым темпом изменений.

IMHO нет ни одного способа устранить проблему. Решение состоит в том, чтобы исследовать возможности, а затем путем проб и ошибок найти то, что лучше всего подходит для ваших конкретных потребностей. Каждый пользователь должен определить, что работает для своей системы, а не использовать метод куки-резака.

У меня, например, есть медиа-сервер с несколькими очень большими файлами. В результате получается всего около 400 файлов, заполняющих накопитель 3 ТБ. Используется только 1% инодов, но используется 95% общей площади. У кого-то еще, с большим количеством небольших файлов, может закончиться inodes, прежде чем они приблизится к заполнению пространства. (В файловых системах ext4, как правило, для каждого файла/каталога используется 1 индексный дескриптор.)
Теоретически общее количество файлов, которые могут содержаться в каталоге, почти бесконечно, практичность определяет, что общее использование определяет реалистичные единицы, а не только возможности файловой системы.

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

 

Не ответ, а лишь некоторые предложения.

Выберите более подходящую FS (файловую систему). Поскольку с исторической точки зрения, все ваши проблемы были достаточно мудрыми, чтобы быть когда-то центральным для ФС, развивающимся в течение десятилетий. Я имею в виду, что более современные FS лучше поддерживают ваши проблемы. Сначала сделайте таблицу решений сравнения, основанную на вашей конечной цели, из [Список FS](https://en.wikipedia.org/wiki/List_of_file_systems).

Я думаю, что пришло время сменить ваши парадигмы. Поэтому я лично предлагаю использовать [распределенные системные FS](https://en.wikipedia.org/wiki/Distributed_file_system#Distributed_file_systems), что означает отсутствие ограничений на размер, количество файлов и т.д. В противном случае вы скорее или позже вызвали новые непредвиденные проблемы.

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

Чтобы преодолеть аппаратные ограничения, вы можете использовать RAID-0.

 

Нет ни одной фигуры, которая "слишком много", если она не превышает пределы ОС. Тем не менее, чем больше файлов в каталоге, независимо от ОС, тем больше времени требуется для доступа к любому отдельному файлу, а для большинства ОС производительность нелинейна, поэтому найти один файл из 10 000 занимает более 10 раз дольше затем найти файл в 1000.

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

 

 У меня была такая же проблема. Попытка сохранить миллионы файлов на сервере Ubuntu в ext4. Закончился запуск моих собственных тестов. Выяснилось, что плоский каталог работает намного лучше, но при этом гораздо проще в использовании:

  [![benchmark](/img/8075e2afbe481ad04195fc1b68c42899.png)](/img/8075e2afbe481ad04195fc1b68c42899.png)

  Написал [статью](https://medium.com/@hartator/benchmark-deep-directory-structure-vs-flat-directory-structure-to-store-millions-of-files-on-ext4-cac1000ca28).