Каковы последствия для производительности миллионов файлов в современной файловой системе?

30

Допустим, мы используем ext4 (с включенным dir_index) для размещения около 3M файлов (в среднем размером 750 КБ), и нам нужно решить, какую схему папок мы будем использовать.

В первом решении мы применяем хеш-функцию к файлу и используем папку с двумя уровнями (будучи 1 символом для первого уровня и 2 символами для второго уровня): поэтому, поскольку filex.forхеш равен abcde1234 , мы будем хранить его в / path / a / bc /abcde1234-filex.for.

Во втором решении мы применяем хеш-функцию к файлу и используем папку с двумя уровнями (будучи 2 символами для первого уровня и 2 символами для второго уровня): поэтому, поскольку filex.forхеш равен abcde1234 , мы будем хранить его в / path / ab / de /abcde1234-filex.for.

Для первого решения у нас будет следующая схема /path/[16 folders]/[256 folders]со средним значением 732 файла в папке (последняя папка, в которой будет находиться файл).

В то время как на втором решении у нас будет /path/[256 folders]/[256 folders]в среднем 45 файлов на папку .

Учитывая, что мы собираемся писать / отсоединять / читать файлы ( но в основном читать ) из этой схемы (в основном, в системе кэширования nginx), имеет ли это значение с точки зрения производительности, если мы выбрали одно или другое решение?

Кроме того, какие инструменты мы могли бы использовать для проверки / тестирования этой установки?

Леандро Морейра
источник
7
Очевидно, что сравнительный анализ поможет. Но ext4 может быть неправильной файловой системой для этого. Я бы посмотрел на XFS.
ewwhite
4
Я бы не стал просто смотреть на XFS, я бы сразу использовал его без лишних слов. Дерево B + каждый раз побеждает хэш-таблицу.
Майкл Хэмптон
Спасибо за советы, сравнительный анализ немного сложен, хотя я пытался, hdparm -Tt /dev/hdXно это не самый подходящий инструмент.
Леандро Морейра
2
Нет, hdparmэто не правильный инструмент, это проверка сырой производительности блочного устройства, а не проверка файловой системы.
HBruijn

Ответы:

28

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

Насколько медленнее, зависит от дизайна файловой системы.

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

Вместо этого файловая система XFS использует дерево B + . Преимущество этого по сравнению с хеш-таблицей или B-деревом состоит в том, что любой узел может иметь несколько дочерних элементов b , где в XFS b изменяется и может достигать 254 (или 19 для корневого узла; и эти числа могут быть устаревшими ). Это дает вам временную сложность O (log b n) , огромное улучшение.

Любая из этих файловых систем может обрабатывать десятки тысяч файлов в одном каталоге, при этом XFS значительно быстрее, чем ext4 в каталоге с таким же количеством инодов. Но вам, вероятно, не нужен единственный каталог с 3M-индексами, так как даже с деревом B + поиск может занять некоторое время. Это то, что привело к созданию каталогов таким способом в первую очередь.

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

Майкл Хэмптон
источник
И для XFS, и для ext4 аппаратное обеспечение, на которое вы устанавливаете файловую систему, окажет огромное влияние на производительность. Медленный диск SATA со скоростью 5400 об / мин может выполнять около 50 операций случайного ввода-вывода в секунду, хороший SAS-диск со скоростью 15000 об / мин может выполнять несколько сотен, а SSD, скорее всего, будет иметь ограниченную пропускную способность и может получать несколько миллионов операций случайного ввода-вывода в секунду. если не больше
Эндрю Хенле
1
Строго говоря, $ O (\ log_b n) $ для фиксированных $ b $ такой же сложности, как и $ O (\ log n) $. Но для ОП фактические константы будут иметь значение.
Хаген фон Айцен
Если с моей файловой системой что-то не так, ext4 не сможет обработать 10 000 файлов в одном каталоге. Выполнение простого ls -lзанимает целую минуту, если каталог выпал из кэша инода. И когда он кешируется, он все равно занимает секунду. Это с SSD и Xeon с тоннами оперативной памяти на веб-сервере с довольно низким трафиком.
Абхи Бекерт
@AbhiBeckert Был ли он обновлен с ext3? Если это так, попробуйте создать новый каталог и переместить файлы в него.
Майкл Хэмптон
@ Хэмптон: Нет. Это (довольно) недавно настроенный сервер на современном оборудовании. Я работал над этой проблемой с нашим системным администратором / центром обработки данных пару месяцев. Мы платим тысячи долларов в месяц за аренду сервера и не получаем от него приемлемой производительности. Похоже, что единственный вариант - перейти к новой структуре каталогов - возможно, использовать хеши вместо дат для имен файлов, чтобы распределить их более равномерно.
Абхи Беккерт
5

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

Оба предложенных вами варианта создают до трех записей inode для каждого созданного файла. Кроме того, 732 файла создадут индекс, который все еще меньше, чем обычные 16 КБ. Для меня это означает, что любой вариант будет выполнять то же самое.

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

sysadmin1138
источник
1
Что делает использование сумм SHA1 (и других, более длинных хеш-сумм) "гораздо более сложной проблемой"? Да, это неудобно для пользователей, но все равно для ОС, файловой системы и других программ.
Кболино
4

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

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

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

Джон Маховальд
источник
1

Одной из проблем является способ сканирования папки.

Представьте себе Java-метод, который запускает сканирование папки.

Он должен будет выделять большой объем памяти и освобождать ее за короткий промежуток времени, что очень тяжело для JVM.

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

Способ полной проверки состоит в том, что для каждой папки выполняется один запуск функции, поэтому JVM выйдет из функции, освободит ОЗУ и снова запустит ее в другой папке.

Это всего лишь пример, но в любом случае иметь такую ​​огромную папку не имеет смысла.

Эндрю Смит
источник
2
Вы используете Java и сканируете папку. Ни один из них не упоминается. В вопросе есть и другие способы обработки папки в Java, помимо сканирования.
user207421
1

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

эталонный тест

Написал статью .

Hartator
источник
Это определенно не ожидаемый результат. Прежде чем вы начнете с этим или порекомендуете это, вы должны глубже понять, почему вы получили этот неожиданный результат.
Майкл Хэмптон