У меня есть каталог с 500 000 файлов. Я хотел бы получить к ним доступ как можно быстрее. Алгоритм требует, чтобы я неоднократно открывал и закрывал их (не может одновременно открывать 500 000 файлов).
Как я могу сделать это эффективно? Первоначально я думал, что могу кэшировать inodes и открывать файлы таким образом, но * nix не предоставляет способа открывать файлы по inode (безопасность или что-то в этом роде).
Другой вариант - просто не беспокоиться об этом и надеяться, что FS хорошо справится с поиском файлов в каталоге. Если это лучший вариант, то какие FS будут работать лучше всего. Некоторые шаблоны имен файлов выглядят быстрее, чем другие? например, 01234.txt против foo.txt
Кстати, это все в Linux.





Пара идей:
а) Если вы можете контролировать структуру каталогов, поместите файлы в подкаталоги.
б) Если вы не можете перемещать файлы, вы можете попробовать другие файловые системы, я думаю, что xfs может быть хорош для каталогов с большим количеством записей?
Подкаталоги могут помочь. Файловая система открывает и кэширует подкаталоги. Один каталог в 500 КБ действительно большой. 1000 каталогов по 500 файлов могут позволить кэширование каталогов меньшего размера и быстрее.
+1 для подкаталогов. При использовании ext [23] количество файлов в одном каталоге увеличивается, это может происходить довольно медленно.
Если у вас достаточно памяти, вы можете использовать ulimit для увеличения максимального количества файлов, которые ваш процесс может открывать за один раз, я успешно справился с 100000 файлов, 500000 также должны работать.
Если это не вариант для вас, попробуйте убедиться, что в вашем кэше dentry достаточно места для хранения всех записей. Кэш dentry - это отображение имени файла -> inode, которое ядро использует для ускорения доступа к файлам на основе имени файла, доступ к огромному количеству различных файлов может эффективно устранить преимущества кеша dentry, а также внести дополнительный удар в производительность. Стандартное ядро 2.6 имеет хэш, содержащий до 256 * МБ ОЗУ за раз, если у вас есть 2 ГБ памяти, вы должны быть в порядке с немногим более 500000 файлов.
Конечно, убедитесь, что вы выполнили соответствующее профилирование, чтобы определить, действительно ли это вызывает «заторможенность».
Другой вопрос, сколько данных в файлах? Является ли серверная часть SQL вариантом?
Я пробовал SQL. Содержимое файлов представляет собой отсортированный список идентификаторов и значений. Имена файлов также являются идентификаторами. Я запустил это с базой данных SQLite, и потребовалось 26 часов, чтобы создать и проиндексировать только идентификаторы файлов. Люди SQL предложили не использовать БД, так как мне нужно только и индексировать.
Предполагая, что ваша файловая система - ext3, ваш каталог индексируется хешированным B-деревом, если dir_index включен. Это даст вам такой же импульс, как и все, что вы могли бы написать в своем приложении.
Если каталог проиндексирован, ваша схема именования файлов не имеет значения.
http://lonesysadmin.net/2007/08/17/use-dir_index-for-your-new-ext3-filesystems/
Спасибо, что не пошли по пути "делать подкаталоги"
Традиционный способ сделать это - использовать хешированные подкаталоги. Предположим, что все имена ваших файлов представляют собой равномерно распределенные хэши, закодированные в шестнадцатеричном формате. Затем вы можете создать 256 каталогов на основе первых двух символов имени файла (так, например, файл 012345678 будет называться 01/2345678). Вы можете использовать два или даже больше уровней, если одного недостаточно.
Пока имена файлов распределены равномерно, это позволит управлять размерами каталогов и, таким образом, ускорит любые операции с ними.
У меня есть каталог со 100000 файлов на ext3 с dir_index. Если я знаю имя файла, почти нет штрафа по времени. Если я сделаю «ls» в каталоге, 3 минуты. После этого все остается в кеше, и никаких временных затрат на операции в этом каталоге не происходит.