38

У меня был каталог, заполненный миллионами изображений в формате gif. Слишком много для команды rm.

Я пытался найти команду поиска следующим образом:

find . -name "*.gif" -print0 | xargs -0 rm

Проблема в том, что это сильно тормозит мою машину и приводит к тайм-ауту клиентов, так как это сервер.

Есть ли способ, чтобы быстрее удалить все эти файлы ... без блокировки машины?

5 ответов5

43

Быстрее не обязательно то, что вы хотите. Возможно, вы захотите работать медленнее, поэтому удаление во время работы отнимает меньше ресурсов.

Используйте nice(1), чтобы понизить приоритет команды.

nice find . -name "*.gif" -delete

Для процессов, связанных с вводом / выводом, nice(1) может быть недостаточно. Планировщик Linux принимает во внимание ввод / вывод, а не только процессор, но вам может потребоваться более точное управление приоритетом ввода / вывода.

ionice -c 2 -n 7 find . -name "*.gif" -delete

Если этого не произойдет, вы также можете добавить сон, чтобы действительно замедлить его.

find . -name "*.gif" -exec sleep 0.01 \; -delete
22

Поскольку вы работаете в Linux, и эта задача, вероятно, связана с вводом / выводом, я советую дать вашей команде приоритет планировщика ввода / вывода с использованием ionice(1):

ionice -c3 find . -name '*.gif' -delete

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

12

Нет.

Нет более быстрого способа, приложения из soft-формата диска. Файлы передаются rm сразу (до предела командной строки, его также можно установить в xargs), что намного лучше, чем вызывать rm для каждого файла. Так что нет, определенно нет более быстрого пути.

Использование nice (или renice в запущенном процессе) помогает только частично, потому что это для планирования ресурсов процессора , а не диска! И использование процессора будет очень низким. Это слабое место в Linux - если один процесс "съедает" диск (т.е. много с ним работает), вся машина зависает. Модифицированное ядро для использования в реальном времени может быть решением.

На сервере я бы позволил другим процессам выполнять свою работу вручную, включая паузы, чтобы сервер "дышал":

find . -name "*.gif" > files
split -l 100 files files.
for F in files.* do
    cat $F | xargs rm
    sleep 5 
done

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

5

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

То есть клонировать части дерева, которые должны быть сохранены, в другой том. Пересоздайте новую чистую файловую систему на исходном томе. Скопируйте сохраненные файлы обратно в их исходные пути. Это примерно похоже на копирование сборки мусора.

Будет некоторое время простоя, но это может быть лучше, чем постоянная плохая производительность и нарушение работы.

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

Например, предположим, что вы хотите удалить все файлы в файловой системе. Какой смысл повторять и удалять по одному? Просто размонтируйте его и выполните "mkfs" поверх раздела, чтобы создать пустую файловую систему.

Или предположим, что вы хотите удалить все файлы, кроме полдюжины важных? Получите полдюжины оттуда и ... "mkfs" поверх.

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

4

Ты пытался:

find . -name "*.gif" -exec rm {} +

Знак + в конце заставит find включить больше файлов для выполнения одной команды rm. Проверьте этот вопрос для более подробной информации.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .