SSD Nodes Learn 🎉 VPS da $5.50/mese
Guide Matt ConnorDi Matt Connor

Quanto spesso eseguire uno scrub ZFS su un VPS

Lo scrub ZFS legge ogni blocco allocato e verifica i checksum. Su un pool VPS con un solo dispositivo rileva i danni, ma non può ripararli: ecco la frequenza.

Cosa fa realmente uno scrub ZFS

Uno scrub ZFS legge ogni blocco allocato nel pool, ricalcola il relativo checksum e confronta il risultato con il checksum memorizzato nel puntatore al blocco padre. Se i due valori non corrispondono, ZFS ripara il blocco usando la ridondanza disponibile nel pool. Nessun'altra operazione di ZFS svolge questa funzione. Le letture normali verificano soltanto i blocchi effettivamente utilizzati, quindi un file che non viene aperto da due anni resta non verificato finché uno scrub non lo legge.

Uno scrub non è fsck, cioè il passaggio di riparazione offline richiesto da altri filesystem. Non esiste una fase di riparazione strutturale, perché ZFS non lascia mai il formato su disco in uno stato danneggiato: ogni scrittura viene eseguita in una nuova posizione e l'uberblock, il puntatore radice del pool, viene aggiornato per ultimo. Uno scrub inoltre non legge l'intero dispositivo. Legge soltanto i blocchi allocati. Per questo motivo un pool quasi vuoto completa lo scrub in pochi minuti, mentre lo stesso pool pieno all'80% richiede molto più tempo.

Lo scrub viene eseguito con la priorità I/O più bassa disponibile in ZFS. Su Linux, zfs_vdev_scrub_max_active ha come valore predefinito 2. Di conseguenza, per ogni vdev possono essere in corso al massimo due letture dello scrub. Un vdev è un dispositivo virtuale, cioè il gruppo di dischi che ZFS tratta come una singola unità. zfs_scrub_min_time_ms ha come valore predefinito 750 e indica il tempo minimo che il thread di sincronizzazione dedica al lavoro dello scrub tra i flush dei gruppi di transazioni, cioè i commit periodici in cui ZFS raggruppa le scritture. Su una macchina inattiva, lo scrub utilizza l'intera capacità del disco. Sotto carico, riduce la propria attività. In un pool con uno o due dispositivi non c'è altra capacità a cui cedere risorse. Per questo la pianificazione è più importante in questo caso rispetto a un chassis di grandi dimensioni con sessanta dischi.

Perché eseguire uno scrub su un pool che non può autoripararsi?

Questa è la frase da cui dipende tutto il resto su un pool di piccole dimensioni. Senza ridondanza, uno scrub rileva la corruzione ma non può correggerla. Un singolo disco virtuale in una VPS costituisce un pool senza mirror e senza parità. ZFS legge il blocco danneggiato, rileva il checksum errato, lo conta nella colonna CKSUM, indica il file e si ferma, perché non esiste una seconda copia da cui ricostruirlo.

È utile conoscere due eccezioni parziali. Per impostazione predefinita, ZFS memorizza una copia aggiuntiva dei metadati (redundant_metadata=all) in una regione diversa del dispositivo. Di conseguenza, uno scrub può riparare una voce di directory o un puntatore a un blocco danneggiati anche su un pool composto da un solo dispositivo. Inoltre, un dataset con copies=2 conserva due copie dei propri blocchi dati, raddoppiando lo spazio utilizzato. Nessuna delle due opzioni protegge dalla perdita del dispositivo. La documentazione della proprietà copies avverte esattamente di questo: non creare un pool striped, impostare copies=2 e ritenere di avere ridondanza.

Su un pool composto da un solo dispositivo, quindi, lo scrub offre un unico vantaggio: una notifica tempestiva e accurata. Trasforma una corruzione silenziosa nel nome di un file in zpool status -v, mentre il backup contiene ancora una versione integra dello stesso file. Questo è un argomento a favore dei backup, non contro gli scrub. Se non hai ancora chiarito la differenza tra un'immagine point-in-time e una vera copia conservata fuori dal server, inizia da perché uno snapshot di una VPS non è un backup, perché il risultato di uno scrub è utile solo se esiste un'altra copia integra.

Anche uno scrub che non rileva problemi è un risultato. Indica che i dati a cui stai per affidarti sono integri, cioè l'informazione che vuoi avere prima di un ripristino o di una migrazione.

Con quale frequenza eseguire lo scrub di un piccolo pool VPS?

Mensile è l'impostazione predefinita corretta ed è quella prevista dai pacchetti. Debian e Ubuntu includono un cron job che esegue lo scrub dei pool integri la seconda domenica di ogni mese. Il sistema periodic di FreeBSD utilizza una soglia espressa in giorni e daily_scrub_zfs_default_threshold è impostato per impostazione predefinita su 35, che il manuale descrive come cinque settimane.

Su un piccolo pool con carico elevato, eseguire lo scrub ogni settimana solitamente costa più di quanto renda. Con uno o due dispositivi, lo scrub compete per la stessa coda usata dall'applicazione e non c'è alcun dispositivo aggiuntivo che possa assorbirne il carico. Su una VPS, la quota I/O è limitata: le operazioni di lettura usate dallo scrub sono operazioni che il database non può eseguire. A fronte di questo costo, lo scrub settimanale offre al massimo tre settimane di preavviso aggiuntivo su un guasto che comunque non è possibile riparare. Questa scelta è sensata solo quando lo scrub ha un costo ridotto.

Misurate la durata, quindi decidete. Eseguite uno scrub manualmente e controllate quanto tempo richiede.

  1. Eseguite sudo zpool scrub tank in una sera con poco carico e registrate il tempo totale a partire da zpool status.
  2. Se termina in molto meno di un'ora e il server resta inattivo durante la notte, la frequenza settimanale è sostenibile.
  3. Se richiede molte ore mentre il pool gestisce traffico, mantenete la frequenza mensile e lasciate che sia il job incluso nel pacchetto a eseguirlo.
  4. Misurate nuovamente la durata ogni volta che il pool cresce in modo significativo, perché la durata dello scrub dipende dalla quantità di dati allocati, non dalla capacità del disco.

Qualunque scelta facciate, annotatela insieme alle altre attività ricorrenti del server. Lo scrub deve comparire nello stesso elenco degli aggiornamenti dei pacchetti e della rotazione dei log: consultate una checklist mensile per la manutenzione dei server Linux.

Avviare, mettere in pausa e interrompere uno scrub

sudo zpool scrub tank
sudo zpool status tank

Mettere in pausa e interrompere sono operazioni diverse. Scegliere quella sbagliata può costringere a ripetere il lavoro per ore.

sudo zpool scrub -p tank
sudo zpool scrub tank
sudo zpool scrub -s tank

-p mette in pausa lo scrub. Lo stato e l'avanzamento della pausa vengono sincronizzati periodicamente sul disco. Di conseguenza, uno scrub in pausa resta tale anche dopo un'esportazione o un riavvio del pool: il pool torna disponibile con lo scrub ancora in pausa, in attesa di un tuo intervento. Eseguendo di nuovo zpool scrub, lo scrub riprende dall'ultimo checkpoint scritto sul disco. -s interrompe invece lo scrub e il successivo scrub avviato ricomincia dall'inizio. Usa -p quando ti serve nuovamente il disco per un'ora. Usa -s quando vuoi eliminare lo scrub.

È utile conoscere anche altri 2 flag. -w attende il completamento dello scrub prima di restituire il controllo. È l'opzione da usare in uno script, per evitare che il passaggio successivo inizi troppo presto. -e esegue lo scrub solo sui file con errori di dati noti, come segnalato da zpool status -v. È il modo più rapido per verificare che un file ripristinato da un backup sia ora integro.

ZFS esegue un solo scrub o resilver alla volta per ogni pool. Il resilver è la ricostruzione eseguita dopo la sostituzione di un dispositivo. Entrambe le operazioni richiedono molte operazioni di I/O. Se un dispositivo è in fase di resilver, lo scrub attende il proprio turno.

Come leggere lo stato di zpool durante uno scrub

Esegui sudo zpool status tank e interpreta i valori del tuo sistema, senza confrontarli con quelli di altri sistemi. Durante uno scrub, la riga scan: mostra il numero di elementi analizzati, il numero di elementi elaborati, il totale, il numero di elementi riparati, la percentuale completata e la stima del tempo rimanente.

Scanned indica la fase dei metadati: ZFS percorre l'albero dei blocchi e raccoglie gli indirizzi che deve leggere. Issued indica la fase dei dati: sono le letture effettivamente inviate al dispositivo, ordinate secondo la posizione sul disco. Lo scrub ordinato spiega la presenza di due contatori; issued è quello che misura l'avanzamento effettivo. All'inizio scanned è molto avanti rispetto a issued e la stima del tempo è poco significativa. Valutala dopo il primo dieci percento.

Repaired conta i byte riscritti a partire da una copia integra. In un pool senza ridondanza questo valore resta zero indipendentemente da ciò che lo scrub rileva. È il concetto illustrato in precedenza, espresso come un numero che puoi monitorare.

Leggi quindi le colonne relative a ogni dispositivo. READ e WRITE contano gli errori di I/O segnalati direttamente dal dispositivo. CKSUM conta i blocchi che non hanno superato la verifica del checksum ed è la colonna che lo scrub serve a valorizzare. Un valore CKSUM diverso da zero su un dispositivo che sembra integro è un errore reale: i dati sono stati restituiti, ma sono errati.

L'ultima riga contiene il verdetto. errors: No known data errors indica un passaggio riuscito. Qualsiasi altro valore richiede l'esecuzione di sudo zpool status -v tank, che stampa l'elenco completo degli errori nei dati rilevati dall'ultimo scrub completo, inclusi i nomi dei file interessati. Ripristina quei file dal backup, esegui sudo zpool clear tank per azzerare i contatori, quindi esegui nuovamente lo scrub. Ogni scrub completo ricrea questo elenco; quindi, se un nome file non compare dopo uno scrub completo senza errori, il problema relativo a quel file è definitivamente risolto.

Quale job periodico di scrub è configurato sul server?

Non dare per scontato che ce ne sia uno e non presumere che ce ne sia uno solo. Il meccanismo varia in base alla piattaforma e al pacchetto. Il formato del pool è identico ovunque, quindi è facile dimenticare che gli strumenti utilizzati non lo sono; in questo caso conta la differenza tra il modo in cui ZFS viene distribuito su FreeBSD rispetto a Linux.

Su FreeBSD il job appartiene al sistema periodic. Imposta questi valori in /etc/periodic.conf:

daily_scrub_zfs_enable="YES"
daily_scrub_zfs_pools="tank"
daily_scrub_zfs_default_threshold="35"

daily_scrub_zfs_pools è un elenco di nomi di pool separati da spazi. Se viene lasciato vuoto, esegue lo scrub su tutti i pool. daily_scrub_zfs_default_threshold indica il numero di giorni tra uno scrub e l'altro quando non è impostata una soglia specifica per il pool; il manuale indica 35 come valore predefinito. Il job daily viene eseguito ogni giorno, ma avvia uno scrub solo quando è trascorso l'intervallo configurato.

Su Linux il comportamento dipende dal pacchetto ZFS della distribuzione. Alcuni sistemi includono entrambi i meccanismi. Esistono timer systemd per singolo pool, zfs-scrub-monthly@tank.timer e zfs-scrub-weekly@tank.timer, che vengono abilitati un pool alla volta. Debian e Ubuntu distribuiscono inoltre /etc/cron.d/zfsutils-linux, che esegue uno script di scrub su ogni pool ONLINE la seconda domenica del mese. Controlla cosa è presente prima di aggiungere altro:

systemctl list-timers 'zfs-*'
ls /etc/cron.d/ | grep -i zfs
sudo zpool history tank | grep scrub

zpool history è la risposta più affidabile, perché registra gli scrub effettivamente avviati dal pool, con le relative date. Due scrub al mese indicano che entrambi i meccanismi sono attivi e che uno dei due deve essere disabilitato. Per abilitare un timer:

sudo systemctl enable --now zfs-scrub-monthly@tank.timer

Lo spazio libero conta più di qualsiasi parametro regolabile

La durata di uno scrub su un pool di piccole dimensioni dipende dalla quantità di dati allocata e dal loro livello di frammentazione. Riempire il pool peggiora entrambi gli aspetti.

Le indicazioni di OpenZFS raccomandano di mantenere oltre il 10% di spazio libero nel pool. Al di sotto di questa soglia, i metaslab, cioè i blocchi su cui opera l'allocatore, iniziano a scendere sotto una soglia del 4% di spazio libero e l'allocatore passa dall'algoritmo first-fit a best-fit. best-fit richiede molta più CPU. La latenza di scrittura aumenta, la frammentazione peggiora e lo scrub successivo diventa ancora più lento, perché la stessa quantità di dati viene letta tramite un numero maggiore di operazioni di lettura più piccole.

La prima misura da adottare non è quindi un parametro regolabile. È eliminare i dati non necessari. Su un sistema ZFS, la causa più comune sono i vecchi snapshot, seguiti da immagini e layer Docker che nessuno ha eliminato e da pacchetti del kernel rimasti dopo gli aggiornamenti. Esegui zfs list -o space prima di modificare qualsiasi altra cosa, perché distingue lo spazio occupato dagli snapshot da quello occupato dai dati attivi.

Poi ci sono i parametri, in breve. Su Linux puoi leggere i valori correnti:

cat /sys/module/zfs/parameters/zfs_scrub_min_time_ms
cat /sys/module/zfs/parameters/zfs_vdev_scrub_max_active

FreeBSD espone gli stessi parametri tramite sysctl, quindi puoi individuare i tuoi con sysctl -a | grep scrub. Aumentarli consente di completare prima lo scrub, ma rallenta le applicazioni. Ridurli produce l'effetto opposto. Su un pool con uno o due dispositivi, nessuna impostazione consente di ottenere entrambi i risultati, perché esiste una sola coda da condividere. Un parametro regolabile risolve raramente un problema di progettazione. Se uno scrub mensile incide sulle prestazioni, la conclusione corretta è che il pool è troppo pieno oppure il dispositivo è troppo lento; un parametro regolabile si limita a spostare il problema.

Il tempo dello scrub è la previsione del resilver

Un resilver esegue la stessa scansione di uno scrub: legge i blocchi allocati, li verifica e scrive quelli mancanti sul dispositivo sostitutivo. Pertanto, la durata dello scrub è la previsione più attendibile della durata di una ricostruzione e del periodo durante il quale il pool opererà con ridondanza ridotta.

ZFS pianifica il lavoro di resilver in modo più aggressivo rispetto a quello dello scrub, quindi una ricostruzione di solito termina prima di uno scrub dello stesso pool. Considera la durata dello scrub come un limite superiore prudenziale. Se lo scrub richiede nove ore, pianifica una finestra di ricostruzione di durata analoga e considera che il guasto di un secondo dispositivo durante quella finestra comporta la perdita del pool. Questo è il motivo pratico per preferire coppie in mirroring invece di un unico gruppo raidz ampio, perché raidz, il layout di parità che ZFS usa al posto di RAID 5, esegue la ricostruzione leggendo ogni dispositivo ancora operativo.

In un pool composto da un solo dispositivo non esiste alcun resilver. Se il dispositivo si guasta, anche il pool diventa indisponibile. Il tempo di ripristino corrisponde al tempo necessario per il restore, quindi misura direttamente il restore. Un restore che non hai mai eseguito non è un piano di ripristino.

Cosa cambia quando si affitta lo storage

Su un VPS il dispositivo a blocchi è virtuale. L'hypervisor presenta un volume che, a sua volta, può risiedere su storage NVMe locale oppure su un volume di rete replicato, con un proprio schema di parità. Questo comporta due conseguenze per gli scrub.

Primo: la ridondanza della piattaforma è invisibile a ZFS e ZFS non può utilizzarla. Se la piattaforma corregge un errore del supporto a un livello sottostante, ZFS non rileva mai il problema. Se la piattaforma restituisce un blocco errato, ZFS lo rileva ma non può correggerlo, perché la copia corretta si trova oltre quel confine.

Secondo: in genere non è possibile leggere i dati SMART (self-monitoring, analysis and reporting technology) del dispositivo sottostante a un disco virtuale. Di conseguenza, gli avvisi preventivi da cui dipende il monitoraggio dello stato del disco su un VPS potrebbero non essere disponibili. Il contatore CKSUM prodotto dagli scrub diventa il principale segnale sotto il tuo controllo.

Se vuoi che ZFS esegua una riparazione invece di limitarsi a segnalare il problema, il pool deve contenere più di un dispositivo nella stessa istanza. Questa è una decisione progettuale, non un parametro da ottimizzare. Scegliendo un VPS con storage invece di un VPS standard ottieni la capacità necessaria, ma la disponibilità di due dispositivi indipendenti dipende dal piano. Esegui lsblk e verifica la configurazione prima di creare un mirror che potrebbe usare due partizioni dello stesso volume. Forniamo server Linux e FreeBSD a noleggio, non un'appliance ZFS gestita. La pianificazione degli scrub e i backup sono quindi a tuo carico. Questo è il compromesso: controllo completo del pool e piena responsabilità della sua manutenzione.

FAQ

Con quale frequenza devo eseguire lo scrub di un pool ZFS su un VPS?

Una volta al mese è adatto per la maggior parte dei pool di piccole dimensioni e corrisponde alla pianificazione predefinita dei pacchetti: un job cron la seconda domenica del mese su Debian e Ubuntu e una soglia predefinita di 35 giorni nel sistema periodic di FreeBSD. Una frequenza settimanale è ragionevole solo dopo aver misurato la durata di uno scrub e aver verificato che termini rapidamente su un server altrimenti inattivo. Su un pool occupato con uno o due dispositivi, lo scrub settimanale utilizza ogni settimana una quantità significativa di I/O delle applicazioni e offre in cambio solo qualche settimana di preavviso aggiuntivo.

Eseguire lo scrub di un pool ZFS su un singolo disco è inutile?

No, purché sia chiaro che cosa consente di ottenere. In assenza di ridondanza, lo scrub rileva la corruzione ma non può ripararla, fatta eccezione per i metadati, di cui ZFS mantiene per impostazione predefinita una copia aggiuntiva. Il risultato è un elenco nominativo dei file danneggiati in zpool status -v, disponibile abbastanza presto da consentirne il ripristino mentre esiste ancora una copia integra altrove. La risposta corretta consiste nel migliorare i backup, perché lo scrub indica esattamente quale file deve essere ripristinato.

Posso sospendere uno scrub ZFS e terminarlo in un secondo momento?

Sì. zpool scrub -p tank lo sospende e lo stato di pausa e l'avanzamento vengono scritti periodicamente su disco, quindi lo scrub resta sospeso anche dopo un'operazione di export o un riavvio. Eseguire di nuovo zpool scrub tank per riprendere dal checkpoint più recente. Non usare zpool scrub -s tank a questo scopo: -s interrompe lo scrub e quello successivo riparte dall'inizio.

Perché lo scrub ZFS è così lento e come posso velocizzarlo?

La durata dello scrub dipende dalla quantità di dati allocati e dalla frammentazione, non dalla capacità del disco. Un pool utilizzato oltre il 90% è lento perché i metaslab con meno del 4% di spazio libero fanno passare l'allocator da first-fit a best-fit; la frammentazione risultante trasforma lo scrub in molte letture di piccole dimensioni. Liberare spazio è generalmente più efficace di qualsiasi parametro di configurazione. È possibile aumentare zfs_scrub_min_time_ms o zfs_vdev_scrub_max_active per assegnare allo scrub una quota maggiore della coda, ma in un pool con uno o due dispositivi tale quota viene sottratta direttamente alle applicazioni.