Комментарии 10
Нюанс критичный, статья годная. Интересно только, что именно за процесс ускоряется в 40 раз.
Если это просмотр пользователем каталога из 10 000 файлов ценой удаления метаданных — сочувствую этому пользователю.
Если это какой-то автоматизированный процесс, использующий вывод ls в своих нуждах — я обязательно оставлю это здесь:
Если это просмотр пользователем каталога из 10 000 файлов ценой удаления метаданных — сочувствую этому пользователю.
Если это какой-то автоматизированный процесс, использующий вывод ls в своих нуждах — я обязательно оставлю это здесь:
Не «удаления метаданных», а «не раскрашивания вывода ls на основании части метаданных»
На самом деле хороший вопрос. Зачем кому-то глазами смотреть 10000 файлов? По поводу скриптов: в статье сказано, что ls не использует раскраску при auto, если не выводится непосредственно в консоль.
Я проводил некоторые исследования в области директорий с большим количеством файлов и могу сказать следующее:
- Современная ФС, такая как ext4 пережёвывает директории с любым количеством файлов без повреждений и заметной потери производительности. Проверял на десятках миллионов.
- Устаревшие ФС, такие как FAT32 могут при обращении к одному файлу тормозить линейно, а иногда и квадратично от к-ва файлов в папке
- Простейшим из быстрейших способов получить список файлов является вызов find без параметров, у ls надо читать ман и приказывать ему не сортировать список (и не раскрашивать, как понятно из статьи)
- Быстрейшим способом очистить такую директорию является rsync с пустой директорией. А rm * подвесит вам шелл. Если рсинка под рукой нет я бы попробовал find -delete или даже "rm -r .".
- Если вы используете ls --color или ls -l то вы не избежите вызова stat() на каждый файл, а это совсем не то же самое, что просто получить список имён.
- Если файлы созданы чем-то вроде touch {1..10000000} то их inode расположены подряд и stat() работает сравнительно быстро
- Если вы годами копили свои файлы (например, не чистили сессии php) то inode раскиданы по таблице и stat() будет очень медленным, особенно на НЖМД
- Вам не нужно читать глазами листинг директории с миллионом файлов. Даже парсить его не нужно, нет и не должно быть таких задач.
4. Если подождать несколько часов, то rm умрёт, сказав что не хватает памяти. find – примерно та-же история. Единственным надёжным и быстрым способом является rsync с пустой.
Проверялось несколько лет назад на (очень) больших нечищеных кэшах squid.
Проверялось несколько лет назад на (очень) больших нечищеных кэшах squid.
Я еще заметил, что после удаления или перемещения файлов из конкретной папки, остаются inode записи (ну я думаю, что это они). Их видно в листинге 'ls -l' как большое число в первой строчке, которая начинается с точки и обозначает текущую директорию.
Вызов 'ls' в такой, вроде бы очищенной (а раньше в ней была пара миллионов файлов), папке занимает длительное время, даже если файлов внутри "уже нет".
Лечится удалением и пересоздание папки.
P.s. Ubuntu Server 14.04, ext4
Лечится удалением и пересоздание папки.Да, как это часто бывает в IT, некоторые структуры данных могут расти но не обучены уменьшатся. 'e2fsck -D' по идее сожмёт такую директорию.
PS Это не inode, они сидят в своей таблице глобальной для всей ФС. Это имена файлов или места, где эти имена ранее были, ведь директория — это такой файл со списком имён файлов и номеров ячеек в таблице inode.
Быстрейшим способом очистить такую директорию является rsync с пустой директорией.
А rm * подвесит вам шелл. Если рсинка под рукой нет я бы попробовал find -delete или даже "rm -r .".
Нет, rsync не является быстрейшим.
unlink perl-a быстре, на выбор:
perl -e 'for(<*>){((stat)[9]<(unlink))}'
perl -e 'chdir "/var/spool/exim/msglog/" or die; opendir D, "."; while ($n = readdir D) { unlink $n }'
13 секунд пользователю съекономили… теперь он сможет намного больше файлов обработать за трудодень…
чего бы еще такого полезного замутить?
чего бы еще такого полезного замутить?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Когда переменная среды ускоряет процесс в 40 раз