La cancellazione di grandi quantità di file su Linux non consuma CPU

Ho generato più di 50 GB di file di cache sul mio server RHEL (e la dimensione tipica di file è 200kb, quindi nessun file è enorme). Quando cerco di eliminare questi file occorre 8-10 ore.

Tuttavia, il problema più grande è che il carico di sistema va critico per questi 8-10 ore. C'è comunque where posso mantenere sotto controllo il carico del sistema durante la cancellazione.

Ho provato ad usare

nice -n19 rm -rf * 

ma questo non aiuta nel carico del sistema.

PS ho chiesto la stessa domanda su superuser.com ma non ho ottenuto una risposta sufficiente così cercando qui.

  • Perché il nome visualizzato in bash differisce da quello in / etc / passwd?
  • Come aggiungere un utente di linux con una password random o non valida da uno script
  • rootsh che esegue il problema nell'utente normale
  • PHP non è in grado di allocare memory
  • Come controllare l'utilizzo della CPU delle librerie in Linux?
  • Odd mdadm output: --examine mostra lo stato dell'arrays fallito, --detail mostra tutto pulito
  • Come posso usare Dirvish senza abilitare gli accessi root in sshd?
  • rsync a NAS copia tutto each volta
  • 9 Solutions collect form web for “La cancellazione di grandi quantità di file su Linux non consuma CPU”

    Ecco alcuni parametri di riferimento per varie operazioni e file system per il tuo riferimento. (In un impegnato sistema naturalmente si avrebbero risultati diversi, ma speriamo che questo vi darà un'idea di cosa aspettarsi).

    Se fossi in vostra sedia cercherò di get un riferimento di base dello scenario:

    • stabilire per quanto tempo l'operazione richiederebbe l'hardware fisso isolato di tutto il resto (e sì, dovrebbe richiedere molto less di 7-8 ore anche su hardware piuttosto vecchio).
    • cercare di aggiungere altre operazioni che in genere si verificano in modo controllato e vedere cosa effettivamente lo fa funzionare così a lungo

    Alcuni numbers.

    Su un notebook da 5 anni, l' ext3 montato rw, noatime, il running top e niente di più creare directory 10k con script shell create10kdirs.sh

     #!/bin/bash for i in $(seq 10000) do mkdir $i done 

    sudo tempo ./create10kdirs.sh
    24.59user
    20.70system
    0: 47.04elapsed
    96% CPU (0avgtext + 0avgdata 0maxresident) k80inputs + 8outputs (1major + 2735150minor) pagefaults 0swaps

    elimina directory 10k con tempo sudo rm -rf
    0.10user
    19.75system
    0: 20.71elapsed
    CPU di 95% (0avgtext + 0avgdata 0maxresident) k0inputs + 8outputs (0major + 222minor) pagefaults 0swaps

    stesso hardware, rw montato ext4 , noatime crea directory 10k con script shell sudo time create10kdirs.sh
    23.96user
    22.31system
    0: 49.26elapsed
    93% CPU (0avgtext + 0avgdata0maxresident) k1896inputs + 8outputs (20major + 2715174minor) pagefaults 0swaps

    elimina directory 10k con tempo sudo rm -rf
    0.13user
    16.96system
    0: 28.21elapsed
    CPU 60% (0avgtext + 0avgdata0maxresident) k10160inputs + 0outputs (1major + 219minor) pagefaults0swaps

    Notebook da 4 anni, xfs montato rw, relatime, nobarrier sudo sudo USB create10kdirs.sh
    14.19user
    13.86system
    0: 29.75elapsed
    94% di CPU (0avgtext + 0avgdata0maxresident) k432inputs + 0outputs (1major + 2735243minor) pagefaults 0swaps

    elimina 10k directory con
    sudo tempo rm -rf
    0.13user
    2.65system
    0: 08.20elapsed
    33% CPU (0avgtext + 0avgdata 0maxresident) k120inputs + 0outputs (1major + 222minor) pagefaults 0swaps

    Conclusione: Questo vecchio hardware potrebbe cancellare 400 k file di piccole size + cartelle su ext3 in circa 21s * 40 = 12m40s. Su xfs (con nobarriers) lo farebbe in circa 5m20s. Dato che in entrambi i casi di prova la macchina di prova non era sotto carico pesante, ma a me sembra che i tuoi problemi non siano strettamente legati alla scelta del filesystem.

    EDIT2 Inoltre, dopo aver eseguito i benchmark sopra, sono andato a provare l'eliminazione con la ricerca. -mindepth 1 -maxdepth 1 -delete

    ei risultati !:

    est3 elimina directory 10k con il tempo di ricerca sudo. -mindepth 1 -maxdepth 1 -delete
    0.04user
    0.44system
    0: 00.88elapsed
    55% di CPU (0avgtext + 0avgdata 0maxresident) k516inputs + 8outputs (1major + 688minor) pagefaults0swaps

    ext4 elimina directory 10k con
    trovare il tempo di sudo. -mindepth 1 -maxdepth 1 -delete
    0.05user
    0.66system
    0: 01.02elapsed
    70% CPU (0avgtext + 0avgdata 0maxresident) k568inputs + 0outputs (1major + 689minor) pagefaults swap

    xfs elimina 10k directory con
    trovare il tempo di sudo. -mindepth 1 -maxdepth 1 -delete
    0.06user
    0.84system
    0: 04.55elapsed
    19% CPU (0avgtext + 0avgdata 0maxresident) k416inputs + 0outputs (3major + 685minor) pagefaults 0swaps

    La conclusione concreta è che rm-rf non è molto intelligente e che sarà sotto-eseguire per grandi alberi. (a condizione che il mio caso di prova sia davvero rappresentativo).

    Nota: Ho anche provato la variante xargs ed è veloce, ma non è così veloce come sopra.

    Come hai detto in un commento, stai utilizzando ext3 .

    È noto che la prestazione rm per i file di grandi size su ext3 è scarsa; è una delle cose che sono state fissate in ext4 . Vedere ad esempio questo post , o kernelnewbies (che menziona le estensioni migliorano le velocità di eliminazione e di troncamento per i file di grandi size).

    Non so quanto si applica alle size dei file tipici. Mi piacerebbe che si applichi alless un po ', poiché con circa 200kB si utilizzerebbero blocchi indiretti su ext3 , in effetti in una sola misura su ext4 .


    Come soluzione (poiché probabilmente non verificherai l'aggiornamento a ext4 solo per questo), eliminare solo pochi file each volta e aggiungere un sleep tra le cancellazioni. Non è bello, ma dovrebbe aiutare a ridurre il carico.

    Inoltre, se perdere i file sulla perdita di potenza non è un problema (poiché è una cache di qualche tipo), potresti metterli in una partizione separata che mkfs nuovo durante l'avvio e utilizzare ext3 senza una rivista o addirittura ext2 . La causa del carico elevato è probabilmente la rivista che viene sciacquata su un disco in conflitto con le letture (hai citato in un altro post che hai molte letture simultanee).

    Forse la shell è la causa del problema. Dovresti usare direttamente trovare: find /dir -mindepth 1 -maxdepth 1 -delete

    Questo può o non può essere correlato: ma ho avuto occasioni in cui rm non poteva gestire il numero di file che ho fornito sulla row di command (tramite l'operatore di stella). Vorrei invece utilizzare il seguente command dalla shell:

     for i in *; do rm -rf $i; done 

    In questo caso si potrebbero cancellare gli alberi, nel qual caso i suddetti non possono fare quello che ti serve. Potrebbe essere necessario suddividere l'operazione di cancellazione in parti, ad esempio

     for i in [a-mA-M]*; do rm -rf $i; done for i in [n-zN-Z]*; do rm -rf $i; done 

    Questo è solo 250.000 file o no, non dovrebbe essere un problema davvero – quale sistema di file si sta utilizzando e questo volume è utilizzato per qualsiasi altra cosa?

    Quando si dispone di un sacco di file come te descritto si invoca each volta il command. Anche tu devi tenere a mente in journaled FS che hai a che fare con colpi di buffer e metadati che possono influenzare notevolmente i tempi di process.

    La tua scommessa migliore è usare il command find come sopra indicato solo con una funzionalità less evidente.

     find / -name filename.* -exec /bin/rm -f '{}' \+ 

    Fondamentalmente il "+" è il tuo amico. Quello che fa è creare i nomi di file in set e invoca il command rm una volta per set. Questo è praticamente lo stesso di quello che esegue xargs, ma non devi preoccuparti delle bandiere corretta se su BSD / Linux.

    Molto curioso quanto lo renda più veloce per te. Quindi rispondi se sei ancora in giro. In bocca al lupo !

    Dopo aver studiato i benchmarks dei filesystem, ho scelto JFS come archivio di file per i miei file video mythtv perché le eliminazioni di file sono veloci (e mythtv aspetta l'eliminazione per finire, rendendo l'IO lenta).

    Potresti anche invocare 'rm' attraverso 'find' e 'xargs' invece di rm -rf. Questo potrebbe essere più veloce:

     find <dir> | xargs rm 

    Come fare per pipeline un elenco di questi file a Perl e utilizzando la sua function di unlink?

     find <dir> | perl -nle 'unlink;' 

    Sono d'accordo che non dovrebbe durare a lungo, ma a seconda dello stoccaggio sottostante viene utilizzato, può essere previsto con le letture intensive. Credo che in definitiva la soluzione migliore è quella di aggiungere altri dischi e dividere le tue attività tra di loro. RAID potrebbe aiutare in alcuni scenari se si scende in quel path. Cosa ti dà iostat in questi tempi? Potresti anche usare un for loop e avvolgere i comandi 'rm' in 'tempo' per get ulteriori informazioni.

    Un'altra possibilità, a seconda della configuration e dell'applicazione di corso, ma forse puoi fare questi file di cache su una partizione diversa e solo formattare l'unità periodicamente, piuttosto che rimuovere i file? Penso che eseguire mkfs abbasserebbe notevolmente il tempo, ma la tua applicazione non sarà disponibile, mentre ciò accade, quindi non sarà l'ideale.

    Mi piace anche l'idea di pulirli più spesso. Dite a cron di programmare qualcosa di simile each ora:

    trovare ./ -maxdepth 1 -type f -name "some pattern" -actime +1 -exec rm -f {} \;

    Questo eliminerebbe tutti i file che sono più vecchi di 24 ore, piuttosto che cercare di farli tutti contemporaneamente.

    Suggerimenti per Linux e Windows Server, quali Ubuntu, Centos, Apache, Nginx, Debian e argomenti di rete.