Elimina 10M + file da ZFS, in modo efficace


30

Ho scritto un programma con errori che ha accidentalmente creato circa 30 milioni di file in / tmp. (Il bug è stato introdotto alcune settimane fa e stava creando un paio di sottodirectory al secondo.) Potrei rinominare / tmp in / tmp2, e ora ho bisogno di eliminare i file. Il sistema è FreeBSD 10, il filesystem di root è zfs.

Nel frattempo una delle unità nello specchio è andata male e l'ho sostituita. L'unità ha due dischi SSD da 120 GB.

Ecco la domanda: la sostituzione del disco rigido e il ripristino dell'intero array hanno richiesto meno di un'ora. L'eliminazione di file / tmp2 è un'altra storia. Ho scritto un altro programma per rimuovere i file e può eliminare solo 30-70 sottodirectory al secondo. Ci vorranno 2-4 giorni per eliminare tutti i file.

Come è possibile che il ripristino dell'intero array richieda un'ora, ma l'eliminazione dal disco richieda 4 giorni? Perché ho prestazioni così cattive? 70 eliminazioni / secondo sembrano prestazioni pessime.

Potrei cancellare manualmente l'inode per / tmp2, ma questo non libererà spazio, giusto?

Questo potrebbe essere un problema con zfs, o i dischi rigidi o cosa?


1
Non sono un esperto di zfs, quindi non posso parlare del tuo tuning delle prestazioni o di cosa potresti fare per migliorarlo (ciò richiederebbe anche molte informazioni e probabilmente sarebbe meglio farlo direttamente da un esperto). Tuttavia, posso dire che il resilvering avviene a livello di blocco, mentre le tue eliminazioni avvengono a livello di filesystem. Il file system avrà principalmente sovraccarico quando si eliminano in questo modo un buffer di inode bagillion.
Spooler,

Si prega di inviare il vostro df -hed zpool liste zfs list.
ewwhite,

5
Scritto un altro programma: rm -rf /tmp2non farà il lavoro?
Thorbjørn Ravn Andersen,

2
Non potresti semplicemente riavviare? /tmpdovrebbe essere un tmpfsfilesystem ed è archiviato in memoria.
Blender,

Risposte:


31

Le eliminazioni in ZFS sono costose. Ancora di più se hai la deduplicazione abilitata sul filesystem (poiché il dereferenziare i file deduplicati è costoso). Le istantanee potrebbero complicare anche le cose.

Potrebbe essere meglio eliminare la /tmpdirectory anziché i dati contenuti all'interno.

Se /tmpè un filesystem ZFS, cancellalo e crea di nuovo.


1
@nagylzs In tal caso, suggerirei di renderlo un file system ZFS separato. Quindi è possibile spostare l'attuale / tmp di mezzo, spostare un nuovo / tmp in posizione ed eliminare i file a piacere del sistema. Risultato: downtime minimo più una leggera riduzione delle prestazioni (mitigabile con ionice, supponendo che FreeBSD ce l' abbia) mentre l'eliminazione è in esecuzione.
un CVn

9
Mi sbagliavo. Era un filesystem separato. Ecco cosa ha funzionato: riavviare in modalità utente singolo, quindi fare "zfs delete zroot / tmp; zfs create zroot / tmp; chmod 41777 / tmp"
nagylzs

6
Sono stati 5 minuti di inattività totale. Fantastico! :-)
nagylzs,

1
Bene, questo parla anche della preoccupazione che avevo, che l'eliminazione dei fiocchi non libera mai spazio a causa delle istantanee. Ma tmp verrà impostato per non creare istantanee periodiche automatiche, giusto ?
JDługosz,

1
In realtà questo era: zfs create -o compressione = on -o exec = on -o setuid = off zroot / tmp; chmod 1777 / zroot / tmp; zfs set mountpoint = / tmp zroot / tmp; Non sono sicuro di come disattivare le istantanee automatiche. C'è "zfs set com.sun: auto-snapshot = false" ma funziona solo su Solaris, credo.
nagylzs,

27

Come è possibile che il ripristino dell'intero array richieda un'ora, ma l'eliminazione dal disco richieda 4 giorni?

Prendi in considerazione un edificio per uffici.

La rimozione di tutti i computer, i mobili e i fissaggi da tutti gli uffici su tutti i piani richiede molto tempo, ma lascia gli uffici immediatamente utilizzabili da un altro cliente.

Demolire l'intero edificio con RDX è molto più veloce, ma è molto probabile che il prossimo cliente si lamenti di quanto sia faticoso il posto.


5
ZFS non è un edificio per uffici :)
developerbmw,

9
@developerbmw non contiene neanche un file o una cartella, ma abbiamo bisogno di concetti metaforici per capire cosa sta succedendo.
JamesRyan,

2
@JamesRyan sì, in realtà è una bella analogia ... Ero solo stupido
Developerbmw,

5

C'è un certo numero di cose che stanno succedendo qui.

Innanzitutto, tutte le moderne tecnologie dei dischi sono ottimizzate per i trasferimenti di massa. Se devi spostare 100 MB di dati, lo faranno molto più velocemente se si trovano in un blocco contiguo invece che sparsi ovunque. Gli SSD aiutano molto qui, ma anche loro preferiscono i dati in blocchi contigui.

In secondo luogo, il resilvering è abbastanza ottimale per quanto riguarda le operazioni del disco. Leggi un enorme blocco contiguo di dati da un disco, esegui alcune operazioni veloci della CPU su di esso, quindi riscrivi in ​​un altro grosso blocco contiguo su un altro disco. Se il potere si interrompe a metà strada, niente di grave: ignorerai semplicemente tutti i dati con checksum errati e proseguirai normalmente.

Terzo, l'eliminazione di un file è molto lenta . ZFS è particolarmente dannoso, ma praticamente tutti i filesystem sono lenti da eliminare. Devono modificare un gran numero di diversi blocchi di dati sul disco e cronometrarli correttamente (cioè attendere) in modo che il filesystem non venga danneggiato in caso di interruzione dell'alimentazione.

Come è possibile che il ripristino dell'intero array richieda un'ora, ma l'eliminazione dal disco richieda 4 giorni?

Il resilver è qualcosa in cui i dischi sono molto veloci, e la cancellazione è qualcosa in cui i dischi sono lenti. Per megabyte di disco, devi solo fare un po 'di resilver. Potresti avere un migliaio di file in quello spazio che devono essere eliminati.

70 eliminazioni / secondo sembrano prestazioni pessime

Dipende. Non ne sarei sorpreso. Non hai menzionato il tipo di SSD che stai utilizzando. I moderni SSD Intel e Samsung sono abbastanza bravi in ​​questo tipo di operazioni (lettura-modifica-scrittura) e funzioneranno meglio. Gli SSD più economici / meno recenti (ad esempio Corsair) saranno lenti. Il numero di operazioni I / O al secondo (IOPS) è il fattore determinante qui.

ZFS è particolarmente lento nell'eliminare le cose. Normalmente, eseguirà le eliminazioni in background in modo da non vedere il ritardo. Se ne stai facendo un numero enorme, non può nasconderlo e deve ritardarti.


Appendice: perché le eliminazioni sono lente?

  • L'eliminazione di un file richiede diversi passaggi. I metadati del file devono essere contrassegnati come "eliminati" e alla fine devono essere recuperati in modo da poter riutilizzare lo spazio. ZFS è un "filesystem strutturato in log" che funziona meglio se si creano e non si eliminano mai. La struttura del registro significa che se si elimina qualcosa, c'è un vuoto nel registro e quindi altri dati devono essere riorganizzati (deframmentati) per colmare il vuoto. Questo è invisibile per l'utente ma generalmente lento.
  • Le modifiche devono essere apportate in modo tale che se si dovesse interrompere parzialmente l'alimentazione, il filesystem rimane coerente. Spesso, ciò significa attendere fino a quando il disco non conferma che i dati sono realmente sul supporto; per un SSD, che può richiedere molto tempo (centinaia di millisecondi). L'effetto netto di questo è che c'è molta più contabilità (cioè operazioni di I / O su disco).
  • Tutte le modifiche sono piccole. Invece di leggere, scrivere e cancellare interi blocchi flash (o cilindri per un disco magnetico) è necessario modificarne un po '. Per fare ciò, l'hardware deve leggere in un intero blocco o cilindro, modificarlo in memoria, quindi scriverlo nuovamente sul supporto. Questo richiede molto tempo.

Non conosco ZFS, ma alcuni file system consentono di scollegare una directory con i contenuti, ma questi contenuti sono stati rimossi in seguito durante una fase di garbage collection / defrag / cleanup. ZFS ha forse qualche utilità per fare una cancellazione così pigra? In realtà non accelererà la cancellazione dell'OP ma probabilmente lo renderebbe meno problematico se si verifica implicitamente durante le pulizie.
Valità,

2

Come è possibile che il ripristino dell'intero array richieda un'ora, ma l'eliminazione dal disco richieda 4 giorni?

È possibile perché le due operazioni funzionano su diversi livelli dello stack del file system. Il resilvering può essere eseguito a basso livello e in realtà non è necessario esaminare singoli file, copiando grossi blocchi di dati alla volta.

Perché ho prestazioni così cattive? 70 eliminazioni / secondo sembrano prestazioni pessime.

Deve fare molta contabilità ...

Potrei cancellare manualmente l'inode per / tmp2, ma questo non libererà spazio, giusto?

Non lo so per ZFS, ma se si potesse recuperare automaticamente da quello, probabilmente, alla fine, farebbe le stesse operazioni che stai già facendo, in background.

Questo potrebbe essere un problema con zfs, o i dischi rigidi o cosa?

Non zfs scrubdire niente?


2

L'eliminazione di molti file non è mai un'operazione veloce.

Al fine di eliminare un file su qualsiasi file system, è necessario leggere l'indice del file, rimuovere (o contrassegnare come eliminato) la voce del file nell'indice, rimuovere tutti gli altri metadati associati al file e contrassegnare lo spazio allocato per il file come inutilizzato. Questo deve essere fatto singolarmente per ogni file da eliminare, il che significa che l'eliminazione di molti file richiede molti piccoli I / O. Per fare ciò in modo da garantire l'integrità dei dati in caso di interruzione dell'alimentazione, si aggiunge un ulteriore sovraccarico.

Anche senza le peculiarità introdotte da ZFS, l'eliminazione di 30 milioni di file significa in genere oltre cento milioni di operazioni I / O separate. Questo sarà richiedere molto tempo anche con un veloce SSD. Come altri hanno già detto, il design di ZFS aggrava ulteriormente questo problema.


2

Ian Howson dà una buona risposta sul perché è lento.

Se si eliminano i file in parallelo, è possibile che si verifichi un aumento della velocità a causa dell'eliminazione che può utilizzare gli stessi blocchi e quindi salvare più volte la riscrittura dello stesso blocco.

Allora prova:

find /tmp -print0 | parallel -j100 -0 -n100 rm

e vedi se funziona meglio delle tue 70 eliminazioni al secondo.


0

Molto semplice se capovolgi il tuo pensiero.

  1. Ottieni un secondo disco (sembra che tu lo abbia già)

  2. Copia tutto dall'unità A all'unità B con rsync, esclusa la directory / tmp. Rsync sarà più lento di una copia di blocco.

  3. Riavvia, utilizzando l'unità B come nuovo volume di avvio

  4. Riformattare l'unità A.

Questo inoltre deframmenterà il tuo disco e ti darà una nuova directory (bene, deframmentare non è così importante con un SSD ma linearizzare i tuoi file non fa mai male a nulla)


Prima di tutto copia tutto tranne / tmp? Quindi includendo / dev e / proc? In secondo luogo, suona un po 'maldestro per me, specialmente su un server di produzione.
Hennes,

Suppongo che sia abbastanza intelligente da escludere non-file, volumi montati e la cartella di memoria virtuale, la maggior parte dei quali non può essere indovinata qui. O fallo da un avvio di manutenzione in cui nessuna di queste cose conta.
Pietro,

Penso che potresti anche zfs send/recv(copiare a livello di blocco) tutti gli altri file system tranne il file system radice (dove si trova / tmp in questo caso) e copiare manualmente i dati rimanenti sul file system radice (escludendo / tmp ovviamente).
user121391

2
Ciò perderà le istantanee e ignorerà alcune delle funzionalità di affidabilità. Manca il punto di usare zfs.
JDługosz,

2
@ JDługosz punti validi, ma rilevanti solo se l'utente se ne frega. Un po 'come "i miei backup sono danneggiati, come ripararli?" -> "Hai bisogno di file di backup?" -> "No." -> "Riformatta".
Pietro,

-1

Hai 30 milioni di voci in un elenco non ordinato. Esegui la scansione dell'elenco per la voce che desideri rimuovere e la rimuovi. Ora hai solo 29.999.999 voci nel tuo elenco non ordinato. Se sono tutti in / tmp, perché non riavviare?


Modificato per riflettere le informazioni nei commenti: Dichiarazione del problema: rimuovere la maggior parte, ma non tutti , dei 30M + file creati in modo errato in / tmp richiede molto tempo.
Problema 1) Il modo migliore per rimuovere un numero elevato di file indesiderati da / tmp.
Problema 2) Comprendere perché è così lento eliminare i file.

Soluzione 1) - / tmp viene ripristinato per svuotarsi all'avvio dalla maggior parte delle distribuzioni * nix. FreeBSD comunque non è uno di questi.
Passaggio 1: copia file interessanti altrove.
Passaggio 2: come root

 $ grep -i tmp /etc/rc.conf  
 clear_tmp_enable="YES" # Clear /tmp at startup.  

Passaggio 3: riavviare.
Passaggio 4: modifica clear_tmp_enable di nuovo su "No".
I file indesiderati ora sono andati come ZFS su FreeBSD ha la caratteristica che "Distruggere un set di dati è molto più veloce dell'eliminazione di tutti i file che risiedono sul set di dati, in quanto non comporta la scansione di tutti i file e l'aggiornamento di tutti i metadati corrispondenti. " quindi tutto ciò che deve fare all'avvio è resettare i metadati per il set di dati / tmp. Questo è molto veloce

Soluzione 2) Perché è così lento? ZFS è un meraviglioso file system che include funzionalità come l'accesso alla directory a tempo costante. Funziona bene se sai cosa stai facendo, ma l'evidenza suggerisce che l'OP non è un esperto ZFS. L'OP non ha indicato come stessero tentando di rimuovere i file, ma suppongo che avrebbero usato una variante di "find regex -exec rm {} \;". Funziona bene con piccoli numeri ma non si ridimensiona perché ci sono tre operazioni seriali in corso 1) ottieni l'elenco dei file disponibili (restituisce 30 milioni di file in ordine di hash), 2) usa regex per scegliere il prossimo file da eliminare, 3 ) dire al sistema operativo di trovare e rimuovere quel file da un elenco di 30 milioni. Anche se ZFS restituisce un elenco dalla memoria e se 'trova' lo memorizza nella cache, il regex deve ancora identificare il file successivo da elaborare dall'elenco e quindi dire al sistema operativo di aggiornare i suoi metadati per riflettere quella modifica e quindi aggiornare l'elenco in modo che non venga nuovamente elaborato.


1
Penso che tu abbia frainteso la domanda. Avevo bisogno di rimuovere la maggior parte dei file. Cioè, file 30M +.
nagylzs,

@nagylzs / tmp viene cancellato al riavvio. Se si desidera eliminare la maggior parte , è necessario conservarne solo alcuni , ovvero meno della metà, quindi copiare quelli che si desidera conservare, quindi riavviare per eliminare il resto. Il motivo per cui le tue eliminazioni sono così lente è che avere un numero elevato di file in una directory genera un ampio elenco non ordinato che deve essere elaborato per trovare il file su cui operare, il che richiede tempo. L'unico problema qui è PEBCAK.
Paul Smith,

Le directory Zfs non sono ordinate ? Ho pensato che zfs gestisse in modo specifico le grandi directory.
JDługosz,

Bene, / tmp non viene cancellato, solo i file relativi a X. Almeno su FreeBSD. Non può essere cancellato comunque all'avvio, perché ci vorrebbero giorni prima che lo script rc si cancella normalmente.
nagylzs,

@JDlugosz - ZFS è molto meglio della maggior parte, ma le liste di inode (che sono tutte le directory) non sono ordinate.
Paul Smith,
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.