¿Cómo hacer `rm` más rápido en ext3 / linux?

32

Tengo el sistema de archivos ext3 montado con opciones predeterminadas. En él tengo algunos archivos ~ 100GB.

La eliminación de cualquiera de estos archivos lleva mucho tiempo (8 minutos) y genera mucho tráfico io, lo que aumenta la carga en el servidor.

¿Hay alguna manera de hacer que la rm no sea tan perjudicial?


fuente
44
Básicamente, ningún método de aquí funcionó, así que desarrollamos el nuestro. Lo describí aquí: depesz.com/index.php/2010/04/04/how-to-remove-backups

Respuestas:

14

La respuesta más interesante fue originalmente enterrada en un comentario sobre la pregunta. Aquí está como una respuesta de primera clase para hacerlo más visible:

Básicamente, ningún método de aquí funcionó, así que desarrollamos el nuestro. Lo describí aquí: http://www.depesz.com/index.php/2010/04/04/how-to-remove-backups/ - depesz 6 de abril de 10 a las 15:15

Ese enlace es un análisis increíblemente exhaustivo de la exploración y el descubrimiento de una solución viable.

Tenga en cuenta también:

El artículo dice:

Como puede ver, utilicé -c2 -n7opciones para ionizar, lo que parece sano.

lo cual es cierto, pero el usuario TafT dice que si no desea ninguna interrupción, -c3'inactivo' sería una mejor opción que -c2'mejor esfuerzo'. Solía -c3construir en segundo plano y descubrió que funcionaba bien sin hacer que la construcción esperara para siempre. Si realmente tiene un uso del 100% de io, entonces -c3no permitirá que la eliminación se complete nunca, pero no espera que eso sea lo que haya hecho según la prueba realizada.

Matt McClure
fuente
18

Actualice a ext4 o algún otro sistema de archivos moderno que use extensiones. Dado que ext3 usa el esquema de bloques indirectos en lugar de extensiones, la eliminación de archivos grandes inevitablemente implica mucho trabajo.

janneb
fuente
6

Puedes probar ionice . No lo hará más rápido, pero podría hacerlo menos perjudicial.

Pausado hasta nuevo aviso.
fuente
4

En términos de eficiencia, el uso de un rm por archivo no es óptimo, ya que requiere una bifurcación y un exec para cada rm.

Suponiendo que tiene una lista.txt que contiene los archivos que desea eliminar, esto sería más eficiente, pero aún así será lento:

xargs -i rm {} < list.txt

Otro enfoque sería: nice -20 xargs -i rm {} < list.txt
(esto tomará menos tiempo pero afectará mucho a su sistema :)

o

No sé qué tan rápido sería, pero:

mv <file-name> /dev/null 

o

Cree un punto de montaje especial con un sistema de archivos rápido (¿utilizando un dispositivo de bucle?), Úselo para almacenar y eliminar sus archivos enormes.
(tal vez mueva los archivos allí antes de eliminarlos, tal vez sea más rápido o tal vez simplemente desmóntelo cuando desee que se vayan los archivos)

o

cat /dev/null > /file/to/be/deleted(así que ahora es de tamaño cero) y si quieres que desaparezca justo rm -rf <file>ahora

o incluso mejor

suelta al gato y solo hazlo # > /file/to/be/emptied


fuente
bueno, estoy eliminando 1 archivo, así que no hay sobrecarga.
stackoverflow.com/questions/1795370/… - verifique esto también
1

Tuve problemas para eliminar el directorio a un ritmo razonable, resultó que el proceso estaba bloqueando el disco y creando una pila de procesos que intentaban acceder al disco. ionice no funcionó, simplemente continuó usando el 99% del disco IO y bloqueó todos los demás procesos.

Aquí está el código de Python que funcionó para mí. Elimina 500 archivos a la vez, luego toma un descanso de 2 segundos para permitir que los otros procesos hagan su trabajo, luego continúa. Funciona genial.

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
Nick Woodhams
fuente
1
Pruébelo en archivos 100G + en el sistema de archivos ext3. El problema es el tamaño del archivo único, no el número de archivos.
En su caso, parece que no funcionaría. Pero tenía un montón de archivos pequeños. Gracias por la respuesta.
Nick Woodhams
1

Mis dos centavos.

Ya tengo este problema. "En las secuencias de comandos secuenciales que deben ejecutarse rápidamente, el proceso elimina una gran cantidad de archivos". Por lo tanto, "rm" hará que la velocidad de la secuencia de comandos se acerque al tiempo de espera / ejecución de E / S.

Entonces, para hacer las cosas más rápido, agregué otro proceso (script bash) lanzado por cron ... como un recolector de basura, elimina todos los archivos en un directorio en particular.

Luego actualicé el script original reemplazando el "rm" por un mv en una "carpeta de basura" (cambie el nombre del archivo agregando un contador al final de su nombre para evitar colisiones).

Esto funciona para mí, el script se ejecuta al menos 3 veces más rápido. pero funciona bien solo si la carpeta de basura y el archivo original están bajo el mismo punto de montaje (mismo dispositivo) para evitar la copia del archivo. (mv en el mismo dispositivo consume menos IO que rm)

Espero que ayude ..

Emmanuel Devaux
fuente
0

También tenga en cuenta que la respuesta de Dennis Williamson, quien sugiere ionice como una solución para la carga, funcionará solo si su dispositivo de bloque usa el programador CFQ io.

famzah
fuente
0

Puede intentar crear un sistema de archivos de bucle para almacenar sus copias de seguridad.

# 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

Luego, cuando desee borrar las copias de seguridad:

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

¡Presto! Todo el sistema de archivos virtual se borra en cuestión de minutos.

anfetamaquina
fuente
no resuelve el problema, ya que solo funcionaría si quisiera eliminar todas las copias de seguridad en un sistema de archivos determinado.
0

Puedes usar multitheading con xargs

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

donde 30 es el número de subprocesos que desea crear. Si está utilizando cero, el sistema crea subprocesos máximos disponibles para el usuario que ejecuta la tarea.

Juan Carlos
fuente
1
findtiene una -deleteopción que es una alternativa mucho mejor.
Ariel
0

mv <nombre de archivo> / dev / null

/ dev / null es un archivo, no un directorio. No puede mover un archivo a un archivo, o corre el riesgo de sobrescribirlo.

Cree un punto de montaje especial con un sistema de archivos rápido (¿utilizando un dispositivo de bucle?), Úselo para almacenar y eliminar sus archivos enormes. (tal vez mueva los archivos allí antes de eliminarlos, tal vez sea más rápido o tal vez simplemente desmóntelo cuando desee que se vayan los archivos)

No creo que esto sea práctico. Usaría innecesariamente más E / S de lo que le gustaría al OP.

Felipe Alvarez
fuente
-1

/ dev / null es un archivo, no un directorio. No puede mover un archivo a un archivo, o corre el riesgo de sobrescribirlo.

En realidad es un dispositivo y todos los datos escritos se descartan, por lo que mv <file> /dev/nulltiene sentido

De Wikipedia, la enciclopedia libre
En sistemas operativos tipo Unix, / dev / null o el dispositivo nulo es un archivo especial que descarta todos los datos escritos en él (pero informa que la operación de escritura se realizó correctamente), y no proporciona datos a ningún proceso que lee de él (produciendo EOF inmediatamente). [1]


fuente
1
Eso está mal e INCREÍBLEMENTE peligroso. / dev / null es un dispositivo, que es un objeto especial similar a un archivo. Si eres root, "mv / some / file / dev / null" BORRARÁ el dispositivo especial / dev / null y moverá tu archivo allí. Entonces, la próxima vez que alguien intente usar / dev / null, usará un archivo real en lugar del dispositivo, y se producirá un desastre. (Cuando Wikipedia dice que "descarta todos los datos escritos en él", eso significa que "cat / some / file> / dev / null" leerá / some / file y descartará los datos que lea, pero eso no afectará el archivo original).
usuario9876