Допустим, мы используем ext4 (с включенным dir_index) для размещения около 3 миллионов файлов (в среднем 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), имеет значение с точки зрения производительности, если мы выберем то или иное решение?
Кроме того, какие инструменты мы могли бы использовать для проверки / тестирования этой настройки?
Причина создания такой структуры каталогов заключается в том, что файловые системы должны находить файл внутри каталога, и чем больше размер каталога, тем медленнее эта операция.
Насколько медленнее, зависит от конструкции файловой системы.
Файловая система ext4 использует B-дерево для хранения записей каталога. Ожидается, что поиск в этой таблице займет O (журнал n) time, которое в большинстве случаев меньше, чем наивная линейная таблица, которую использовали ext3 и предыдущие файловые системы (а когда это не так, каталог слишком мал для того, чтобы это действительно имело значение).
Файловая система XFS использует B + дерево вместо. Преимущество этого перед хеш-таблицей или B-деревом в том, что у любого узла может быть несколько дочерних элементов. б, где в XFS б варьируется и может достигать 254 (или 19 для корневого узла; и эти числа могут быть устаревшими). Это дает вам временную сложность O (журналб п), огромное улучшение.
Любая из этих файловых систем может обрабатывать десятки тысяч файлов в одном каталоге, при этом XFS значительно быстрее, чем ext4, в каталоге с таким же количеством inodes. Но вам, вероятно, не нужен единственный каталог с 3M inode, поскольку даже с деревом B + поиск может занять некоторое время. Это то, что в первую очередь привело к созданию каталогов таким образом.
Что касается предложенных вами структур, первый вариант, который вы указали, - это именно то, что показано в примерах nginx. Он будет хорошо работать в любой файловой системе, хотя XFS все равно будет иметь некоторое преимущество. Второй вариант может работать немного лучше или немного хуже, но он, вероятно, будет довольно близок даже по тестам.
По моему опыту, одним из факторов масштабирования является размер inode с учетом стратегии разделения хеш-имен.
Оба предложенных вами варианта создают до трех записей inode для каждого созданного файла. Кроме того, 732 файла создадут индексный дескриптор размером меньше обычных 16 КБ. Для меня это означает, что любой вариант будет работать одинаково.
Я аплодирую вам за ваш короткий гашиш; предыдущие системы, с которыми я работал, брали sha1sum данного файла и сращивали каталоги на основе этой строки, что было гораздо более сложной проблемой.
Конечно, любой вариант поможет уменьшить количество файлов в каталоге до того, что кажется разумным для xfs, ext4 или любой другой файловой системы. Непонятно, что лучше, пришлось бы проверить, чтобы сказать.
Лучше всего провести сравнительный анализ вашего приложения, имитирующего что-то вроде реальной рабочей нагрузки. В противном случае придумайте что-то, что специально имитирует множество небольших файлов. Говоря об этом, вот файл с открытым исходным кодом под названием smallfile. В его документации есть ссылки на некоторые другие инструменты.
hdparm
длительный ввод-вывод не так полезен. Он не будет отображать множество мелких операций ввода-вывода или гигантские записи каталога, связанные с очень большим количеством файлов.
У меня была такая же проблема. Попытка сохранить миллионы файлов на сервере Ubuntu в ext4. Завершился запуск собственных тестов. Выяснилось, что плоский каталог работает лучше, но при этом проще в использовании:
Написал статья.
Одна из проблем - способ сканирования папки.
Представьте себе метод Java, который запускает сканирование папки.
Ему придется выделить большой объем памяти и освободить ее за короткий период времени, что очень тяжело для JVM.
Лучше всего организовать структуру папок так, чтобы каждый файл находился в отдельной папке, например. год месяц день.
Полное сканирование выполняется так, что для каждой папки выполняется один запуск функции, поэтому JVM выйдет из функции, освободит оперативную память и снова запустит ее в другой папке.
Это всего лишь пример, но в любом случае иметь такую огромную папку не имеет смысла.