Как сделать `rm` быстрее на ext3 / linux?

32

У меня есть файловая система ext3 с параметрами по умолчанию. На нем у меня есть около 100 ГБ файлов.

Удаление любого из таких файлов занимает много времени (8 минут) и вызывает много трафика, что увеличивает нагрузку на сервер.

Есть ли способ сделать rm не таким разрушительным?


источник
4
В принципе, ни один из методов не работал, поэтому мы разработали наш собственный. Описано здесь: depesz.com/index.php/2010/04/04/how-to-remove-backups

Ответы:

14

Самый интересный ответ изначально был похоронен в комментарии к вопросу. Вот как ответ первого класса, чтобы сделать его более заметным:

В принципе, ни один из методов не работал, поэтому мы разработали наш собственный. Описано здесь: http://www.depesz.com/index.php/2010/04/04/how-to-remove-backups/ - depesz 6 апреля 2010 года в 15:15

Эта ссылка представляет собой невероятно тщательный анализ исследования и обнаружения работоспособного решения.

Обратите внимание также:

В статье говорится:

Как вы можете видеть, я использовал -c2 -n7параметры, которые кажутся нормальными.

это правда, но пользователь TafT говорит, что если вы не хотите прерывать работу, тогда -c3«холостой ход» будет лучшим выбором, чем -c2«наилучшие усилия». Он привык -c3строить в фоновом режиме и нашел, что он работает хорошо, не заставляя сборку ждать вечно. Если вы действительно используете 100% io, -c3удаление не будет завершено, но он не ожидает, что это то, что вы использовали на основе сработавшего теста.

Мэтт МакКлюр
источник
18

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

janneb
источник
6

Вы можете попробовать Ионис . Это не сделает его быстрее, но это может сделать его менее разрушительным.

Приостановлено до дальнейшего уведомления.
источник
4

С точки зрения эффективности, использование одного rm на файл не является оптимальным, поскольку для каждого rm требуются форк и exec.

Предполагая, что у вас есть list.txt, содержащий файлы, которые вы хотите удалить, это будет более эффективно, но все равно будет медленно:

xargs -i rm {} < list.txt

Другой подход заключается в следующем: nice -20 xargs -i rm {} < list.txt
(это займет меньше времени, но сильно повлияет на вашу систему :)

или

Я не знаю, как быстро это будет, но:

mv <file-name> /dev/null 

или

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

или

cat /dev/null > /file/to/be/deleted(так что теперь он нулевого размера), и если вы хотите, чтобы он исчез прямо rm -rf <file>сейчас

или даже лучше

брось кота и просто сделай # > /file/to/be/emptied


источник
Ну, я удаляю 1 файл, поэтому нет никаких накладных расходов.
stackoverflow.com/questions/1795370/… - проверьте это тоже
1

У меня были проблемы с получением каталога для удаления в разумном темпе, оказалось, что процесс блокировал диск и создавал кучу процессов, пытающихся получить доступ к диску. ionice не работал, он просто продолжал использовать 99% дискового ввода-вывода и блокировал все остальные процессы.

Вот код Python, который работал для меня. Он удаляет 500 файлов за раз, затем делает 2-секундный перерыв, чтобы позволить другим процессам выполнять свою работу, а затем продолжает. Работает отлично.

import os, os.path
import time

for root, dirs, files in os.walk('/dir/to/delete/files'):
    file_num = 0
    for f in files:
        fullpath = os.path.join(root, f)
        os.remove(fullpath)
        if file_num%500 == 1:
            time.sleep(2)
            print "Deleted %i files" % file_num
        file_num = file_num + 1
Ник Вудхэмс
источник
1
Попробуйте на 100G + файлы на файловой системе ext3. Проблема в размере одного файла, а не в количестве файлов.
В вашем случае это звучит так, как будто это не сработает. Но у меня было множество маленьких файлов. Спасибо за ответ.
Ник Вудхэмс
1

Мои два цента.

У меня уже есть эта проблема. «В последовательном сценарии, который должен выполняться быстро, процесс удаляет много файлов» .. Таким образом, «rm» сделает скорость выполнения этого сценария близкой к времени ожидания ввода-вывода.

Чтобы ускорить процесс, я добавил еще один процесс (bash-скрипт), запущенный для каждого cron ... как сборщик мусора, он удаляет все файлы в определенном каталоге.

Затем я обновил оригинальный скрипт, заменив «rm» на mv на «мусорную папку» (переименуйте файл, добавив в конце его имя счетчик, чтобы избежать столкновения).

У меня это работает, скрипт запускается как минимум в 3 раза быстрее. но это работает хорошо, только если папка для мусора и исходный файл находятся в одной точке монтирования (на одном устройстве), чтобы избежать копирования файла. (mv на том же устройстве потребляет меньше IO, чем rm)

Надеюсь, что поможет ..

Эммануэль Дево
источник
0

Также обратите внимание, что ответ Денниса Уильямсона, который предлагает ionice в качестве обходного пути для нагрузки, будет работать, только если ваше блочное устройство использует планировщик CFQ io.

famzah
источник
0

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

# dd if=/dev/zero of=/path/to/virtualfs bs=100M count=1024 # 100 MB * 1024 = 100 GB
# mke2fs /path/to/virtualfs
# mount -t ext2 /path/to/virtualfs /mnt/backups -o loop

Затем, когда вы хотите очистить резервные копии:

# umount /mnt/backups
# mke2fs /path/to/virtualfs
# mount -t ext2 /path/to/virtualfs /mnt/backups -o loop

Presto! Вся виртуальная файловая система очищается за считанные минуты.

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

Вы можете использовать многоголовку с Xargs

find . -type f | xargs -P 30 rm -rf 

где 30 - количество потоков, которые вы хотите создать. Если вы используете ноль, система создает максимальное количество потоков, доступных пользователю, выполняющему задачу.

Хуан Карлос
источник
1
findесть -deleteвариант, который является гораздо лучшей альтернативой.
Ариэль
0

mv <имя-файла> / dev / null

/ dev / null - это файл, а не каталог. Не удается переместить файл в файл, или вы рискуете перезаписать его.

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

Я не думаю, что это практично. Он будет использовать излишне больше I / O, чем хотелось бы OP.

Фелипе Альварес
источник
-1

/ dev / null - это файл, а не каталог. Не удается переместить файл в файл, или вы рискуете перезаписать его.

На самом деле это устройство, и все данные, записанные на него, удаляются, поэтому mv <file> /dev/nullимеет смысл

Из Википедии, свободной энциклопедии
В Unix-подобных операционных системах / dev / null или нулевое устройство - это специальный файл, который отбрасывает все записанные в него данные (но сообщает, что операция записи выполнена успешно) и не предоставляет никаких данных ни одному процессу, который читает из него (немедленно получая EOF). [1]


источник
1
Это неправильно и невероятно опасно. / dev / null - это устройство, представляющее собой специальный файлоподобный объект. Если вы root, «mv / some / file / dev / null» удалит специальное устройство / dev / null и переместит ваш файл туда! Поэтому в следующий раз, когда кто-то попытается использовать / dev / null, он будет использовать реальный файл вместо устройства, и это приведет к катастрофе. (Когда Википедия говорит, что она «отбрасывает все записанные в нее данные», это означает, что «cat / some / file> / dev / null» будет читать / some / file и отбрасывать прочитанные вами данные, но это не повлияет на исходный файл).
user9876