SSD Nodes Learn 🎉 VPS vanaf $5.50/mnd
Gidsen Matt ConnorDoor Matt Connor

Hoe vaak moet ik een ZFS scrub draaien op een VPS?

Een ZFS scrub controleert checksums van alle actieve blokken. Bij een VPS met een enkele schijf kan ZFS fouten wel detecteren maar niet herstellen. Lees hier het advies.

Wat een ZFS scrub daadwerkelijk doet

Een ZFS scrub leest elk toegewezen blok in de pool, berekent de checksum opnieuw en vergelijkt het resultaat met de checksum die is opgeslagen in de bovenliggende blokpointer. Wanneer deze twee niet overeenkomen, herstelt ZFS het blok met behulp van de redundantie die in de pool aanwezig is. Geen enkel ander proces in ZFS voert deze taak uit. Bij normale leesacties worden alleen de blokken gecontroleerd die u op dat moment benadert; een bestand dat u al twee jaar niet hebt geopend, blijft dus ongecontroleerd totdat een scrub het leest.

Een scrub is niet hetzelfde als fsck, de offline reparatiefase die andere bestandssystemen nodig hebben. Er is geen structurele reparatiefase, omdat ZFS de on-disk structuur nooit in een defecte staat achterlaat: elke schrijfactie gaat naar een nieuwe locatie en de uberblock, de root-pointer van de pool, wordt als laatste bijgewerkt. Een scrub leest bovendien niet het volledige apparaat. Het leest alleen toegewezen blokken, wat verklaart waarom een bijna lege pool binnen enkele minuten gescrubd is, terwijl diezelfde pool bij een bezettingsgraad van 80% veel langer nodig heeft.

De scrub draait met de laagste I/O-prioriteit die ZFS kent. Op Linux staat zfs_vdev_scrub_max_active standaard op 2, wat betekent dat er maximaal twee scrub-leesacties tegelijkertijd per vdev (virtual device, de groep schijven die ZFS als één eenheid behandelt) in de wachtrij staan. zfs_scrub_min_time_ms staat standaard op 750; dit is de minimale tijd die de sync-thread besteedt aan scrub-werkzaamheden tussen de transaction group flushes door, de periodieke commits waarin ZFS schrijfacties groepeert. Op een inactief systeem gebruikt de scrub de volledige schijfcapaciteit. Onder belasting wijkt de scrub uit. Bij een pool met slechts één of twee apparaten is er geen ruimte om uit te wijken, wat de reden is dat scheduling hier belangrijker is dan in een grote behuizing met zestig schijven.

Waarom een pool scrubben die zichzelf niet kan herstellen?

Dit is de beslissende factor voor een kleine pool. Zonder redundantie detecteert een scrub corruptie, maar kan deze niet verhelpen. Een enkele virtuele schijf in een VPS is een pool zonder mirror en zonder pariteit. ZFS leest het beschadigde blok, de checksum-controle faalt, het blok wordt geteld in de CKSUM-kolom en het bestand wordt benoemd. Daar stopt het proces, omdat er geen tweede kopie is om het blok te reconstrueren.

Er zijn twee gedeeltelijke uitzonderingen die het vermelden waard zijn. ZFS slaat standaard een extra kopie van metadata op (redundant_metadata=all), geschreven naar een ander gedeelte van het apparaat. Hierdoor kan een scrub een beschadigd directory-item of blokpointer repareren, zelfs op een pool met één apparaat. Een dataset met copies=2 houdt bovendien twee kopieën van zijn datablokken bij, tegen dubbele opslagkosten. Geen van beide methoden biedt bescherming als het apparaat volledig uitvalt. De documentatie bij de copies-eigenschap waarschuwt hier expliciet voor: bouw geen striped pool, stel copies=2 in en ga er vervolgens vanuit dat u redundantie heeft.

Op een pool met één apparaat levert een scrub u dus één ding op: tijdige en nauwkeurige notificatie. Het zet stille corruptie om in een bestandsnaam in zpool status -v, terwijl uw back-up nog een goede versie van dat bestand bevat. Dat is een argument vóór back-ups, niet tegen het scrubben. Als u het verschil tussen een point-in-time image en een echte off-box kopie nog niet heeft vastgesteld, begin dan bij waarom een VPS-snapshot geen back-up is, omdat een scrub-resultaat alleen nuttig is als er ergens anders een intacte kopie bestaat.

Een scrub die niets vindt, is eveneens een resultaat. Het bevestigt dat de data waarop u wilt vertrouwen intact is; precies wat u moet weten voordat u een restore of migratie uitvoert.

Hoe vaak moet u een kleine VPS-pool scrubben?

Maandelijks is de juiste standaard, en dit is wat de pakketten al aannemen. Debian en Ubuntu leveren een cron-job mee die gezonde pools op de tweede zondag van elke maand scrubt. Het periodic-systeem van FreeBSD werkt met een drempelwaarde in dagen, en daily_scrub_zfs_default_threshold staat standaard op 35, wat de handleiding omschrijft als vijf weken.

Wekelijks scrubben op een drukke kleine pool kost meestal meer dan het oplevert. Bij één of twee apparaten concurreert de scrub om dezelfde wachtrij als uw applicatie, en er is geen reserveapparaat om dit op te vangen. Op een VPS is de I/O-toewijzing eindig, dus leesacties die de scrub verbruikt, zijn leesacties die uw database niet krijgt. Tegenover die kosten levert wekelijks scrubben u maximaal drie weken eerder waarschuwing op over een defect dat u toch niet kunt repareren. Die afweging is alleen zinvol als de scrub goedkoop is.

Meet de tijd en beslis dan. Voer één scrub handmatig uit en kijk hoe lang het duurt.

  1. Voer sudo zpool scrub tank uit op een rustige avond en noteer de totale tijd vanuit zpool status.
  2. Als het ruim binnen een uur klaar was en de server 's nachts inactief is, is wekelijks scrubben betaalbaar.
  3. Als het vele uren duurde terwijl de pool verkeer verwerkte, blijf dan bij maandelijks en laat de geconfigureerde taak het werk doen.
  4. Meet de tijd opnieuw wanneer de pool merkbaar groeit, omdat de duur van de scrub afhangt van de toegewezen data, niet van de schijfcapaciteit.

Wat u ook kiest, noteer het naast uw andere terugkerende serverwerkzaamheden. Een scrub hoort in hetzelfde lijstje thuis als pakket-upgrades en log-rotatie: zie een maandelijkse Linux-serveronderhoudschecklist.

Starten, pauzeren en stoppen van een scrub

sudo zpool scrub tank
sudo zpool status tank

Pauzeren en stoppen zijn verschillende bewerkingen; het kiezen van de verkeerde optie kan leiden tot uren aan herhaald werk.

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

-p pauzeert het proces. De pauzestatus en de voortgang worden periodiek naar de schijf geschreven, waardoor een gepauzeerde scrub een export of een reboot overleeft: de pool komt terug met de scrub nog steeds in de pauzestand, wachtend op uw actie. Het opnieuw uitvoeren van zpool scrub hervat het proces vanaf het laatste checkpoint dat naar de schijf is geschreven. -s stopt de scrub daarentegen volledig, waardoor de volgende scrub die u start weer vanaf het begin begint. Gebruik -p wanneer u de schijf voor een uur nodig heeft. Gebruik -s wanneer u de scrub volledig wilt beëindigen.

Er zijn nog twee andere vlaggen die nuttig zijn om te kennen. -w wacht tot de scrub is voltooid voordat de opdracht terugkeert; dit is wat u nodig heeft in een script, zodat de volgende stap niet te vroeg begint. -e scrubt alleen de bestanden met bekende datafouten zoals gerapporteerd door zpool status -v; dit is de snelle manier om te bevestigen dat een bestand dat u vanuit een back-up heeft hersteld, nu in orde is.

ZFS voert per pool slechts één scrub of resilver (de herbouw die volgt op het vervangen van een apparaat) tegelijk uit, omdat beide processen intensief gebruikmaken van I/O. Als een apparaat aan het resilveren is, wacht uw scrub op zijn beurt.

Hoe u de zpool status leest tijdens een scrub

Voer sudo zpool status tank uit en lees uw eigen cijfers in plaats van deze te vergelijken met die van anderen. Tijdens een scrub bevat de scan:-regel een gescand cijfer, een uitgegeven cijfer, een totaal, een hersteld cijfer, een voltooiingspercentage en een schatting van de resterende tijd.

Scanned is de metadatafase: ZFS doorloopt de block tree en verzamelt de adressen die het moet lezen. Issued is de datafase: de leesopdrachten die daadwerkelijk naar het apparaat zijn verzonden, gesorteerd op schijfvolgorde. Een gesorteerde scrub is de reden dat er twee tellers zijn, en issued is de teller die de werkelijke voortgang bijhoudt. In het begin loopt scanned ver vooruit op issued en zegt de tijdsinschatting weinig. Beoordeel deze pas na de eerste tien procent.

Repaired telt het aantal bytes dat is herschreven vanaf een goede kopie. Op een pool zonder redundantie blijft dit op nul staan, ongeacht wat de scrub vindt; dit is het eerdere punt, maar dan uitgedrukt in een cijfer dat u kunt monitoren.

Bekijk vervolgens de kolommen per apparaat. READ en WRITE tellen de I/O-fouten die het apparaat zelf heeft gerapporteerd. CKSUM telt de blokken waarvan de checksum-verificatie is mislukt, en CKSUM is de kolom waarvoor een scrub wordt uitgevoerd. Een niet-nulwaarde in CKSUM op een apparaat dat gezond lijkt, is reëel: de data is teruggekomen, maar was corrupt.

De laatste regel is het oordeel. errors: No known data errors betekent dat de test is geslaagd. Iets anders betekent dat u sudo zpool status -v tank moet uitvoeren, wat de volledige lijst met datafouten sinds de laatste volledige scrub afdrukt, inclusief de getroffen bestandsnamen. Herstel deze bestanden vanaf een back-up, voer sudo zpool clear tank uit om de tellers te resetten en voer daarna opnieuw een scrub uit. Elke volledige scrub herbouwt die lijst, dus een bestandsnaam die na een volledige, geslaagde scrub ontbreekt, is definitief verloren.

Welke periodieke scrub-taak staat op uw systeem?

Ga er niet vanuit dat er een taak is, en ga er niet vanuit dat er slechts één is. Het mechanisme verschilt per platform en per pakket. Het pool-formaat is overal identiek, waardoor men snel vergeet dat de tooling eromheen dat niet is, en de manier waarop ZFS wordt geleverd op FreeBSD in vergelijking met Linux is hier het relevante verschil.

Op FreeBSD bevindt de taak zich in het periodic-systeem. Stel deze in via /etc/periodic.conf:

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

daily_scrub_zfs_pools is een door spaties gescheiden lijst met pool-namen; als u deze leeg laat, worden alle pools gescrubd. daily_scrub_zfs_default_threshold is het aantal dagen tussen scrubs wanneer er geen pool-specifieke drempelwaarde is ingesteld; de handleiding geeft 35 als standaardwaarde. De dagelijkse taak draait elke dag; deze start pas een scrub zodra de drempelwaarde is verstreken.

Op Linux hangt het af van het ZFS-pakket van uw distributie, en sommige systemen gebruiken beide mechanismen tegelijk. Er zijn per-pool systemd-timers, zfs-scrub-monthly@tank.timer en zfs-scrub-weekly@tank.timer, die per pool worden ingeschakeld. Debian en Ubuntu leveren ook /etc/cron.d/zfsutils-linux, dat een script uitvoert dat elke ONLINE pool scrubt op de tweede zondag van de maand. Controleer wat u heeft voordat u iets toevoegt:

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

zpool history is het eerlijke antwoord, omdat dit de scrubs registreert die de pool daadwerkelijk heeft gestart, inclusief datums. Twee scrubs per maand betekent dat beide mechanismen actief zijn en dat er één moet worden verwijderd. Om een timer in te schakelen:

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

Vrije ruimte is belangrijker dan welke instelling dan ook

De duur van een scrub op een kleine pool wordt bepaald door de hoeveelheid toegewezen data en de mate van versnippering. Het vullen van de pool verergert beide factoren.

Het advies voor OpenZFS is om de vrije ruimte op een pool boven de 10% te houden. Daaronder beginnen metaslabs, de brokken waar de allocator mee werkt, de drempel van 4% vrije ruimte te overschrijden en schakelt de allocator over van first-fit naar best-fit. Best-fit is aanzienlijk intensiever voor de CPU. De schrijflatentie neemt toe, fragmentatie volgt, en de daaropvolgende scrub duurt nog langer omdat dezelfde hoeveelheid data nu binnenkomt als meer en kleinere leesacties.

De eerste maatregel is daarom geen instelling, maar het verwijderen van bestanden. Oude snapshots zijn op een ZFS-systeem de gebruikelijke oorzaak, gevolgd door Docker-images en lagen die niemand heeft opgeschoond en kernelpakketten die zijn achtergebleven na upgrades. Voer zfs list -o space uit voordat u iets anders aanpast, omdat dit het onderscheid maakt tussen ruimte die door snapshots wordt ingenomen en ruimte die door actieve data wordt gebruikt.

Dan de instellingen, in het kort. Op Linux kunt u de huidige waarden uitlezen:

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

FreeBSD stelt dezelfde parameters beschikbaar via sysctl, dus zoek de uwe met sysctl -a | grep scrub. Het verhogen ervan zorgt ervoor dat de scrub sneller klaar is, maar maakt uw applicatie trager. Het verlagen ervan heeft het tegenovergestelde effect. Op een pool met één of twee apparaten biedt geen enkele instelling beide voordelen, omdat er slechts één wachtrij is om te verdelen. Een instelling lost zelden een ontwerpfout op. Als een maandelijkse scrub voor problemen zorgt, is de eerlijke conclusie dat de pool te vol is of het apparaat te traag, en een instelling verplaatst het probleem slechts.

Scrub-tijd is uw preview voor een resilver

Een resilver voert dezelfde actie uit als een scrub: het leest de toegewezen blokken, verifieert deze en schrijft de ontbrekende blokken naar de vervangende schijf. De tijd die een scrub in beslag neemt, is daarom de meest betrouwbare indicatie van hoe lang een rebuild zal duren en hoe lang de pool met verminderde redundantie zal draaien.

ZFS plant resilver-taken agressiever in dan scrub-taken, waardoor een rebuild meestal sneller klaar is dan een scrub van dezelfde pool. Beschouw uw scrub-tijd als een conservatieve bovengrens. Als de scrub negen uur duurt, plan dan een rebuild-venster van die omvang en houd er rekening mee dat een tweede schijfdefect binnen dat venster leidt tot het verlies van de pool. Dat is het praktische argument voor mirrored pairs in plaats van één brede raidz-groep, aangezien raidz, de pariteitsindeling die ZFS gebruikt in plaats van RAID 5, herbouwt door elke overgebleven schijf te lezen.

Bij een pool met één schijf vindt er helemaal geen resilver plaats. Als de schijf uitvalt, gaat de pool verloren. Uw hersteltijd is in dat geval uw restore-tijd; meet daarom de restore. Een restore die u nog nooit heeft uitgevoerd, is geen herstelplan.

Wat verandert er wanneer u de schijf huurt

Op een VPS is het block device virtueel. De hypervisor presenteert een volume, en daaronder kan zich lokale NVMe bevinden, of een gerepliceerd netwerkvolume met eigen pariteit. Dit heeft twee gevolgen voor scrubs.

Ten eerste is de redundantie van het platform onzichtbaar voor ZFS, en ZFS kan deze niet benutten. Als het platform een mediafout onder uw niveau herstelt, ziet ZFS het probleem nooit. Als het platform een foutief block doorgeeft, detecteert ZFS dit wel, maar kan het dit niet herstellen omdat de juiste kopie zich aan de andere kant van die grens bevindt.

Ten tweede kunt u doorgaans geen SMART (self-monitoring, analysis and reporting technology)-gegevens uitlezen voor het apparaat onder een virtuele schijf. De vroegtijdige waarschuwingen waar schijfgezondheidsbewaking op een VPS van afhankelijk is, zijn daardoor mogelijk helemaal niet beschikbaar. De CKSUM-teller van uw scrubs wordt daarmee het belangrijkste signaal waarover u beschikt.

Wilt u dat ZFS herstelt in plaats van alleen rapporteert, dan heeft de pool meer dan één apparaat binnen dezelfde instantie nodig. Dat is een beslissing die bij het plannen moet worden genomen, niet bij het tunen. Kiezen voor een storage-VPS in plaats van een reguliere VPS levert u de capaciteit op, al hangt het van het abonnement af of u ook daadwerkelijk twee onafhankelijke apparaten krijgt. Voer lsblk uit en controleer dit voordat u een mirror bouwt op wat achteraf twee slices van hetzelfde volume blijken te zijn. Wij verhuren Linux- en FreeBSD-servers, geen beheerd ZFS-apparaat; het scrub-schema en de back-ups zijn dus uw verantwoordelijkheid. Dat is de afspraak: volledige controle over de pool, volledige verantwoordelijkheid voor het onderhoud.

FAQ

Hoe vaak moet ik een ZFS-pool op een VPS scrubben?

Maandelijks is voor de meeste kleine pools voldoende en dit komt overeen met wat de pakketten standaard al doen: een cron-job op de tweede zondag van de maand op Debian en Ubuntu, en een standaarddrempel van 35 dagen in het periodic-systeem van FreeBSD. Wekelijks is alleen redelijk als u de tijd van een scrub heeft gemeten en heeft gezien dat deze snel voltooit op een verder inactief systeem. Bij een drukke pool met één of twee schijven verbruikt een wekelijkse scrub elke week aanzienlijke I/O-capaciteit van applicaties, terwijl het slechts enkele weken extra waarschuwingstijd oplevert.

Is het scrubben van een ZFS-pool met één schijf zinloos?

Nee, zolang u duidelijk bent over wat het u oplevert. Zonder redundantie detecteert een scrub corruptie zonder deze te kunnen herstellen, behalve voor metadata, waarvan ZFS standaard een extra kopie bewaart. Wat u krijgt is een gespecificeerde lijst met beschadigde bestanden in zpool status -v, vroeg genoeg om ze te herstellen terwijl er elders nog een goede kopie bestaat. De juiste reactie is betere back-ups, aangezien de scrub u precies vertelt welk bestand u moet herstellen.

Kan ik een ZFS-scrub pauzeren en later voltooien?

Ja. zpool scrub -p tank pauzeert de scrub; de pauzestatus en voortgang worden periodiek naar de schijf geschreven, waardoor de scrub gepauzeerd blijft na een export of een reboot. Voer zpool scrub tank opnieuw uit om door te gaan vanaf het laatste controlepunt. Gebruik hiervoor niet zpool scrub -s tank: -s stopt de scrub volledig en de volgende scrub begint weer vanaf het begin.

Waarom is mijn ZFS-scrub zo traag en kan ik dit versnellen?

De scrubtijd is afhankelijk van de toegewezen data en fragmentatie, niet van de schijfcapaciteit. Een pool die voor meer dan 90% vol is, is traag omdat metaslabs met minder dan 4% vrije ruimte de allocator dwingen van 'first-fit' naar 'best-fit' over te schakelen, en de daaropvolgende fragmentatie verandert de scrub in vele kleine leesacties. Ruimte vrijmaken helpt meestal meer dan welke instelling dan ook. U kunt zfs_scrub_min_time_ms of zfs_vdev_scrub_max_active verhogen om de scrub een groter deel van de wachtrij toe te wijzen, maar bij een pool met één of twee schijven gaat dat deel direct ten koste van uw applicaties.