Можно ли (по производительности) иметь сотни или тысячи файлов в одном каталоге Linux?

Хорошо известно, что в Windows каталог со слишком большим количеством файлов будет иметь ужасную производительность при попытке открыть один из них. У меня есть программа, которая должна выполняться только в Linux (в настоящее время она находится на Debian-Lenny, но я не хочу быть конкретным в этом дистрибутиве) и записывает много файлов в тот же каталог (который действует как репозиторий). Под "многими" я имею в виду десятки каждый день, а это значит, что через год я ожидаю иметь что-то вроде 5000-10000 файлов. Они должны храниться (как только файл создается, он никогда не удаляется), и предполагается, что жесткий диск имеет требуемую емкость (если нет, он должен быть обновлен). Эти файлы имеют широкий диапазон размеров: от нескольких килобайт до десятков МБ (но не намного больше). Имена всегда являются числовыми значениями, сгенерированными поэтапно. Я беспокоюсь о долговременной деградации производительности, поэтому я бы спросил:

  • Можно ли написать все в один каталог? Или я должен думать о создании набора подкаталогов для каждого файла X?
  • Должен ли я использовать определенную файловую систему для такого каталога?
  • Какая была бы более надежная альтернатива? Специализированная файловая система? Что?
  • Любые другие соображения/рекомендации?

Ответ 1

Это очень зависит от файловой системы.

ext2 и ext3 имеют жесткий предел 32 000 файлов в каталоге. Это несколько больше, чем вы просите, но достаточно близко, чтобы я не рискнул. Кроме того, ext2 и ext3 будут выполнять линейное сканирование при каждом обращении к файлу по имени в каталоге.

ext4 предположительно устраняет эти проблемы, но я не могу ручаться за него лично.

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

Итак, если вам действительно нужно огромное количество файлов, я бы использовал XFS или, возможно, ext4.

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

Для описываемого приложения я, вероятно, создаю иерархию вместо этого, так как вряд ли будет какое-либо дополнительное кодирование или умственное усилие для кого-то, кто смотрит на него. В частности, вы можете назвать свой первый файл "00/00/01" вместо "000001".

Ответ 2

Если вы используете файловую систему без индексации каталогов, то очень плохая идея иметь много файлов в одном каталоге (скажем, > 5000).

Однако, если у вас есть индексация каталогов (которая включена по умолчанию для более поздних дистрибутивов в ext3), то это не такая проблема.

Однако, он разрывает довольно много инструментов, чтобы иметь много файлов в одном каталоге (например, "ls" будет stat() все файлы, что занимает много времени). Вы, вероятно, можете легко разбить его на подкаталоги.

Но не переусердствуйте. Не используйте излишние уровни вложенных подкаталогов без необходимости, это просто использует много inode и делает операции метаданных медленнее.

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

Ответ 3

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

Просто используйте файловую систему по вашему выбору. Создайте случайные тестовые данные для 100, 1000 и 10000 записей. Затем измерьте время, необходимое вашей системе для выполнения действия, которое вас беспокоит по времени (открытие файла, чтение 100 случайных файлов и т.д.).

Затем вы сравниваете время и используете лучшее решение (помещаете их все в один каталог, каждый год помещаете в новый каталог, помещаете каждый месяц каждого года в новый каталог).

Я не знаю подробно, что вы используете, но создание каталога - это однократная (и, вероятно, довольно простая) операция, поэтому почему бы не сделать это вместо изменения файловых систем или попыток использования еще более трудоемких материалов?

Ответ 4

В дополнение к другим ответам, если огромный каталог управляется известным приложением или библиотекой, вы можете рассмотреть его замену на что-то еще, например:

  • a GDBM индексный файл; GDBM - очень распространенная библиотека, предоставляющая индексированный файл, который сопоставляет произвольному ключу (последовательности байтов) произвольное значение (другая последовательность байтов).
  • возможно, таблица внутри базы данных, например MySQL или PostGresQL. Будьте осторожны с индексацией.
  • другой способ индексирования данных

Преимущества вышеупомянутых подходов включают в себя:

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

Недостатком такого подхода является то, что они не отображаются в виде файлов. Но поскольку ответ MarkR напоминает вам, ls ведет себя довольно плохо на огромных каталогах.

Если вы придерживаетесь подхода к файловой системе, многие программы, использующие большое количество файлов, организуют их в подкаталогах, таких как aa/ ab/ ac/... ay/ az/ ba/... bz/...

Ответ 5

  • Можно ли написать все в один каталог? Или я должен думать о создании набора подкаталогов для каждого файла X?

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

  • Должен ли я использовать определенную файловую систему для такого каталога?

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

  • Какая была бы более надежная альтернатива? Специализированная файловая система? Что?

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

  • Любые другие соображения/рекомендации?

См. выше. С добавлением, что от 5000 до 10000 файлов в одном каталоге не должно быть проблемой. Насколько мне известно, на практике он не произвольно замедляет файловую систему, за исключением таких утилит, как "ls" и "rm". Но вы могли бы сделать:

find * | xargs echo
find * | xargs rm

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

Я забыл сказать, что вы могли бы использовать что-то, называемое "разреженные файлы" http://en.wikipedia.org/wiki/Sparse_file

Ответ 6

Плохо для производительности иметь огромное количество файлов в одном каталоге. Для проверки наличия файла обычно требуется проверка O (n) каталога. Для создания нового файла потребуется такое же сканирование с заблокированным каталогом, чтобы предотвратить изменение состояния каталога до создания нового файла. Некоторые файловые системы могут быть более умными в этом отношении (используя B-деревья или что-то еще), но чем меньше связей ваша реализация имеет сильные и слабые стороны файловой системы, тем лучше для долгосрочного обслуживания. Предположите, что кто-то может решить запустить приложение в сетевой файловой системе (хранилище или даже облачное хранилище). Огромные каталоги - ужасная идея при использовании сетевого хранилища.