Назад | Перейти на главную страницу

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

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

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

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

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

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

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

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

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

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

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

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

Вы можете дать ionice попытка. Это не ускорит работу, но сделает ее менее разрушительной.

С точки зрения эффективности использование одного rm на файл не является оптимальным, поскольку для каждого rm требуется fork и 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

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

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

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

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

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

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

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

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

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

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

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

# 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

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

Вы можете использовать многопоточность с xargs

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

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

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

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

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

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

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

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

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