Come rendere `rm` più veloce su ext3 / linux?


32

Ho un filesystem ext3 montato con opzioni predefinite. Su di esso ho alcuni file da ~ 100 GB.

La rimozione di uno di questi file richiede molto tempo (8 minuti) e provoca molto traffico io, aumentando il carico sul server.

C'è un modo per rendere la RM non così dirompente?


4
Fondamentalmente nessun metodo da qui ha funzionato, quindi abbiamo sviluppato il nostro. Descritto qui: depesz.com/index.php/2010/04/04/how-to-remove-backups

Risposte:


14

La risposta più interessante è stata originariamente sepolta in un commento sulla domanda. Ecco come una risposta di prima classe per renderlo più visibile:

Fondamentalmente nessun metodo da qui ha funzionato, quindi abbiamo sviluppato il nostro. Descritto qui: http://www.depesz.com/index.php/2010/04/04/how-to-remove-backups/ - depesz 6 aprile 10 alle 15:15

Tale collegamento è un'analisi incredibilmente approfondita dell'esplorazione e della scoperta di una soluzione praticabile.

Nota anche:

L'articolo dice:

Come puoi vedere, ho usato le -c2 -n7opzioni per ionice, che sembrano sane.

il che è vero, ma l'utente TafT afferma che se non si desidera alcuna interruzione, -c3"inattivo" sarebbe una scelta migliore di -c2"migliore sforzo". Ha usato -c3per costruire in background e ha trovato che funzioni bene senza far aspettare per sempre la build. Se utilizzi davvero il 100% di io -c3, non eliminerai mai l'eliminazione ma non si aspetta che sia quello che hai basato sul test funzionato.


18

Esegui l'aggiornamento a ext4 o ad altri file system moderni che utilizzano extents. Poiché ext3 utilizza lo schema a blocchi indiretti anziché estensioni, l'eliminazione di file di grandi dimensioni comporta inevitabilmente molto lavoro.



4

In termini di efficienza, l'utilizzo di 1 rm per file non è ottimale, poiché richiede un fork e un exec per ogni rm.

Supponendo che tu abbia un list.txt contenente i file che desideri rimuovere, sarebbe più efficiente ma sarà comunque lento:

xargs -i rm {} < list.txt

Un altro approccio sarebbe: nice -20 xargs -i rm {} < list.txt
(ciò richiederà meno tempo ma influirà notevolmente sul sistema :)

o

Non so quanto sarebbe veloce ma:

mv <file-name> /dev/null 

o

Crea uno speciale mount point con un filesystem veloce (usando un dispositivo loop?), Usalo per archiviare ed eliminare i tuoi file enormi.
(magari sposta i file lì prima di eliminarli, forse è più veloce o magari smonta quando vuoi che i file scompaiano)

o

cat /dev/null > /file/to/be/deleted(quindi ora ha dimensioni zero) e se vuoi che scompaia proprio rm -rf <file>ora

o anche meglio

lascia cadere il gatto e fallo # > /file/to/be/emptied


bene, sto rimuovendo 1 file, quindi non c'è sovraccarico.


1

Ho avuto problemi a far cancellare la directory a un ritmo ragionevole, ho scoperto che il processo stava bloccando il disco e creando un ammasso di processi che tentavano di accedere al disco. ionice non ha funzionato, ha continuato a utilizzare il 99% dell'IO del disco e bloccato tutti gli altri processi.

Ecco il codice Python che ha funzionato per me. Elimina 500 file alla volta, quindi fa una pausa di 2 secondi per consentire agli altri processi di svolgere il proprio lavoro, quindi continua. Funziona alla grande.

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
Provalo su file 100G + sul filesystem ext3. Il problema è nella dimensione del singolo file, non nel numero di file.

Nel tuo caso sembra che non funzionerebbe. Ma avevo un sacco di piccoli file. Grazie per il feedback.
Nick Woodhams,

1

I miei due centesimi.

Ho già questo problema. "Negli script sequenziali che devono essere eseguiti velocemente, il processo rimuove molti file" .. Quindi "rm" renderà tale velocità dello script vicina al tempo di attesa / esecuzione di IO.

Quindi, per rendere le cose più veloci, ho aggiunto un altro processo (script bash) lanciato per cron .. come un garbage collector rimuove tutti i file in una particolare directory.

Quindi ho aggiornato lo script originale sostituendo "rm" con un mv in una "garbage folder" (rinominare il file aggiungendo un contatore alla fine del suo nome per evitare la collisione).

Questo funziona per me, lo script viene eseguito almeno 3 volte più velocemente. ma funziona bene solo se la cartella Garbage e il file originale si trovano nello stesso punto di montaggio (stesso dispositivo) per evitare la copia del file. (mv sullo stesso dispositivo consuma meno IO di rm)

Spero che ti aiuti ..


0

Si noti inoltre che la risposta di Dennis Williamson, che suggerisce ionice come soluzione alternativa per il carico, funzionerà solo se il dispositivo a blocchi utilizza lo scheduler CFQ io.


0

Potresti provare a creare un file system loop su cui archiviare i tuoi backup.

# 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

Quindi, quando si desidera cancellare i backup:

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

Presto! L'intero file system virtuale viene cancellato in pochi istanti.


non risolve il problema, poiché funzionerebbe solo se volessi rimuovere tutti i backup su un determinato filesystem.

0

Puoi usare il multitheading con xargs

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

dove 30 è il numero di thread che si desidera creare. Se si utilizza zero, il sistema crea i thread massimi disponibili per l'utente che esegue l'attività.


1
findha -deleteun'opzione che è un'alternativa molto migliore.
Ariel,

0

mv <nome-file> / dev / null

/ dev / null è un file non una directory. Impossibile spostare un file in un file o rischi di sovrascriverlo.

Crea uno speciale mount point con un filesystem veloce (usando un dispositivo loop?), Usalo per archiviare ed eliminare i tuoi file enormi. (magari sposta i file lì prima di eliminarli, forse è più veloce o magari smonta quando vuoi che i file scompaiano)

Non penso sia pratico. Userebbe inutilmente più I / O di quanto OP vorrebbe.


-1

/ dev / null è un file non una directory. Impossibile spostare un file in un file o rischi di sovrascriverlo.

In realtà è un dispositivo e tutti i dati scritti su di esso vengono scartati, quindi mv <file> /dev/nullha senso

Da Wikipedia, l'enciclopedia libera
Nei sistemi operativi simili a Unix, / dev / null o il dispositivo null è un file speciale che scarta tutti i dati scritti su di esso (ma riporta che l'operazione di scrittura è riuscita) e non fornisce dati a nessun processo che legge da esso (producendo immediatamente EOF). [1]


1
Questo è sbagliato e INCREDIBILMENTE pericoloso. / dev / null è un dispositivo, che è un oggetto simile a un file speciale. Se sei root, "mv / some / file / dev / null" ELIMINA il dispositivo speciale / dev / null e sposta il tuo file lì! Quindi la prossima volta che qualcuno cerca di usare / dev / null useranno un file reale invece del dispositivo, e ne conseguirà un disastro. (Quando Wikipedia dice che "scarta tutti i dati scritti su di esso", ciò significa che "cat / some / file> / dev / null" leggerà / some / file e scarterà i dati letti, ma ciò non influirà sul file originale).
user9876
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.