SSD Nodes Learn 🎉 VPS ab $5.50/Monat
Anleitungen Matt ConnorVon Matt Connor

ZFS-Scrub-Zeitplan für einen kleinen VPS-Pool

Ein Scrub prüft jeden belegten Block. Im VPS-Pool mit nur einem Gerät findet er Schäden, kann sie aber nicht reparieren. So oft sollten Sie ihn starten.

Was ein ZFS-Scrub tatsächlich macht

Ein ZFS-Scrub liest jeden belegten Block im Pool, berechnet dessen Prüfsumme neu und vergleicht das Ergebnis mit der Prüfsumme, die im übergeordneten Blockzeiger gespeichert ist. Stimmen die beiden Werte nicht überein, repariert ZFS den Block anhand der im Pool vorhandenen Redundanz. Keine andere Funktion in ZFS übernimmt diese Aufgabe. Normale Lesevorgänge prüfen nur die Blöcke, auf die tatsächlich zugegriffen wird. Eine Datei, die Sie seit zwei Jahren nicht geöffnet haben, bleibt daher ungeprüft, bis ein Scrub sie liest.

Ein Scrub ist nicht fsck, der Offline-Reparaturdurchlauf, den andere Dateisysteme benötigen. Eine strukturelle Reparaturphase gibt es nicht, weil ZFS das On-Disk-Format nie in einem beschädigten Zustand hinterlässt: Jeder Schreibvorgang erfolgt an einer neuen Position, und der Uberblock, der Root-Zeiger des Pools, wird zuletzt aktualisiert. Ein Scrub liest außerdem nicht das gesamte Gerät. Er liest nur belegte Blöcke. Deshalb ist der Scrub eines fast leeren Pools in wenigen Minuten abgeschlossen, während derselbe Pool bei 80 % Belegung deutlich länger benötigt.

Der Scrub läuft mit der niedrigsten von ZFS verwendeten I/O-Priorität. Unter Linux ist zfs_vdev_scrub_max_active standardmäßig auf 2 gesetzt. Dadurch sind pro vdev (Virtual Device, die von ZFS als eine Einheit behandelte Laufwerksgruppe) höchstens zwei Scrub-Lesevorgänge gleichzeitig aktiv. zfs_scrub_min_time_ms ist standardmäßig auf 750 gesetzt. Das ist die Mindestzeit, die der Sync-Thread zwischen den Flushes von Transaction Groups für Scrub-Arbeiten aufwendet. Transaction Groups sind die periodischen Commits, zu denen ZFS Schreibvorgänge bündelt. Auf einem nicht ausgelasteten Rechner nutzt der Scrub das gesamte Laufwerk. Unter Last tritt er zurück. Bei einem Pool mit einem oder zwei Geräten gibt es keinen anderen Bereich, in den er ausweichen kann. Deshalb ist die Zeitplanung hier wichtiger als bei einem großen Chassis mit sechzig Laufwerken.

Warum einen Pool prüfen, der sich nicht selbst reparieren kann?

Dieser Satz entscheidet bei einem kleinen Pool über alles Weitere. Ohne Redundanz erkennt ein Scrub Beschädigungen, kann sie aber nicht beheben. Eine einzelne virtuelle Festplatte in einem VPS ist ein Pool ohne Mirror und ohne Parität. ZFS liest den beschädigten Block, stellt fest, dass die Prüfsumme nicht stimmt, zählt den Fehler in der Spalte CKSUM, nennt die Datei und beendet den Vorgang. Es gibt keine zweite Kopie, aus der der Block wiederhergestellt werden könnte.

Zwei teilweise Ausnahmen sollten Sie kennen. ZFS speichert Metadaten standardmäßig mit einer zusätzlichen Kopie (redundant_metadata=all) in einem anderen Bereich des Geräts. Dadurch kann ein Scrub einen beschädigten Verzeichniseintrag oder Blockzeiger auch in einem Pool mit nur einem Gerät reparieren. Ein Dataset mit copies=2 speichert außerdem zwei Kopien seiner Datenblöcke, allerdings zum doppelten Speicherplatzbedarf. Keine dieser Maßnahmen schützt, wenn das Gerät ausfällt. Die Dokumentation der Eigenschaft copies warnt genau davor: Erstellen Sie keinen Striped-Pool, setzen Sie copies=2 und gehen Sie davon aus, dass damit Redundanz vorhanden ist.

Bei einem Pool mit nur einem Gerät liefert der Scrub daher eine Information: eine frühzeitige und genaue Benachrichtigung. Er macht aus einer unbemerkten Beschädigung einen Dateinamen in zpool status -v, solange Ihr Backup noch eine intakte Version dieser Datei enthält. Das spricht für Backups, nicht gegen Scrubs. Wenn Sie den Unterschied zwischen einem zeitpunktbezogenen Image und einer echten Kopie außerhalb des Servers noch nicht geklärt haben, beginnen Sie mit warum ein VPS-Snapshot kein Backup ist. Ein Scrub-Ergebnis hilft nur, wenn an anderer Stelle eine intakte Kopie vorhanden ist.

Auch ein Scrub ohne Befund ist ein Ergebnis. Er zeigt Ihnen, dass die Daten, denen Sie vertrauen wollen, intakt sind. Genau das müssen Sie vor einer Wiederherstellung oder Migration wissen.

Wie oft sollten Sie einen kleinen VPS-Pool prüfen?

Monatlich ist der richtige Standardwert. Dies entspricht auch den Vorgaben der Pakete. Debian und Ubuntu liefern einen cron-Job aus, der intakte Pools am zweiten Sonntag jedes Monats prüft. Das periodic-System von FreeBSD verwendet einen Schwellenwert in Tagen. daily_scrub_zfs_default_threshold ist standardmäßig auf 35 gesetzt. Im Handbuch wird dieser Wert als fünf Wochen beschrieben.

Eine wöchentliche Prüfung eines ausgelasteten kleinen Pools verursacht normalerweise mehr Kosten, als sie Nutzen bringt. Bei einem oder zwei Geräten konkurriert die Prüfung mit Ihrer Anwendung um dieselbe Warteschlange. Es gibt kein zusätzliches Gerät, das die Last aufnehmen kann. Auf einem VPS ist das verfügbare I/O-Kontingent begrenzt. Die Lesevorgänge der Prüfung stehen daher Ihrer Datenbank nicht zur Verfügung. Dem steht gegenüber, dass eine wöchentliche Prüfung höchstens drei Wochen früher vor einem Fehler warnt, den Sie ohnehin nicht reparieren können. Dieser Aufwand ist nur sinnvoll, wenn die Prüfung wenig kostet.

Messen Sie die Dauer und entscheiden Sie dann. Führen Sie eine Prüfung manuell aus und beobachten Sie, wie lange sie dauert.

  1. Führen Sie sudo zpool scrub tank an einem ruhigen Abend aus und erfassen Sie die Gesamtdauer ab zpool status.
  2. Wenn die Prüfung deutlich weniger als eine Stunde dauerte und der Server über Nacht nicht ausgelastet ist, ist eine wöchentliche Prüfung vertretbar.
  3. Wenn sie während des laufenden Netzwerkverkehrs viele Stunden dauerte, bleiben Sie beim monatlichen Intervall und überlassen Sie die Ausführung dem mitgelieferten Job.
  4. Messen Sie die Dauer erneut, sobald der Pool deutlich wächst. Die Dauer der Prüfung hängt von der Menge der zugewiesenen Daten ab, nicht von der Festplattenkapazität.

Unabhängig von Ihrer Entscheidung sollten Sie sie neben Ihren anderen regelmäßigen Serverarbeiten dokumentieren. Eine Pool-Prüfung gehört auf dieselbe Liste wie Paketaktualisierungen und Log-Rotation: siehe eine monatliche Checkliste für die Linux-Serverwartung.

Scrub starten, pausieren und beenden

sudo zpool scrub tank
sudo zpool status tank

Pausieren und Beenden sind unterschiedliche Vorgänge. Wenn Sie den falschen Vorgang auswählen, kann das stundenlange Wiederholungen verursachen.

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

-p pausiert den Scrub. Der Pausenzustand und der Fortschritt werden regelmäßig auf die Festplatte geschrieben. Daher bleibt ein pausierter Scrub auch nach einem Export oder Reboot pausiert. Der Pool wird mit dem pausierten Scrub wieder eingebunden und wartet auf Sie. Wenn Sie zpool scrub erneut ausführen, wird der Scrub ab dem letzten auf der Festplatte gespeicherten Prüfpunkt fortgesetzt. -s beendet den Scrub dagegen. Der nächste von Ihnen gestartete Scrub beginnt dann von vorn. Verwenden Sie -p, wenn Sie die Festplatte eine Stunde lang anderweitig benötigen. Verwenden Sie -s, wenn der Scrub vollständig beendet werden soll.

Zwei weitere Flags sollten Sie kennen. -w wartet, bis der Scrub abgeschlossen ist, bevor der Befehl zurückkehrt. Das benötigen Sie in einem Script, damit der nächste Schritt nicht zu früh startet. -e prüft nur die Dateien mit bekannten Datenfehlern, die von zpool status -v gemeldet wurden. Damit können Sie schnell bestätigen, dass eine aus dem Backup wiederhergestellte Datei jetzt fehlerfrei ist.

ZFS führt pro Pool jeweils nur einen Scrub oder Resilver aus. Resilver bezeichnet den Wiederaufbau nach dem Ersetzen eines Geräts. Beide Vorgänge verursachen intensive I/O-Aktivität. Wenn gerade ein Gerät resilvered wird, wartet Ihr Scrub, bis er an der Reihe ist.

So lesen Sie den Status von zpool während eines Scrubs

Führen Sie sudo zpool status tank aus und verwenden Sie Ihre eigenen Werte, statt sie mit den Werten anderer Systeme zu vergleichen. Während eines Scrubs enthält die Zeile scan: einen Wert für die gescannte Datenmenge, einen Wert für die ausgeführten Lesevorgänge, die Gesamtmenge, die reparierte Datenmenge, den Fertigstellungsgrad und eine Schätzung der verbleibenden Zeit.

Scanned bezeichnet die Metadatenphase: ZFS durchläuft den Blockbaum und erfasst die Adressen, die gelesen werden müssen. Issued bezeichnet die Datenphase: Die Lesevorgänge werden tatsächlich an das Gerät gesendet und nach der Reihenfolge auf dem Datenträger sortiert. Der sortierte Scrub ist der Grund für die zwei Zähler. Issued zeigt den tatsächlichen Fortschritt. Zu Beginn liegt Scanned weit vor Issued, und die Zeitschätzung ist kaum aussagekräftig. Bewerten Sie den Wert erst nach den ersten zehn Prozent.

Repaired zählt die Bytes, die aus einer fehlerfreien Kopie neu geschrieben wurden. Auf einem Pool ohne Redundanz bleibt dieser Wert unabhängig vom Ergebnis des Scrubs bei null. Damit wird der zuvor genannte Punkt als beobachtbarer Zahlenwert dargestellt.

Lesen Sie anschließend die Spalten für die einzelnen Geräte. READ und WRITE zählen die vom Gerät selbst gemeldeten I/O-Fehler. CKSUM zählt Blöcke, deren Prüfsummenprüfung fehlgeschlagen ist. CKSUM ist die Spalte, die ein Scrub füllt. Ein Wert ungleich null bei CKSUM auf einem scheinbar fehlerfreien Gerät ist ein echter Fehler: Die Daten wurden zurückgegeben, waren aber fehlerhaft.

Die letzte Zeile enthält das Ergebnis. errors: No known data errors bedeutet, dass der Pool fehlerfrei ist. Jeder andere Wert bedeutet, dass Sie sudo zpool status -v tank ausführen müssen. Der Befehl gibt die vollständige Liste der Datenfehler seit dem letzten vollständigen Scrub aus, einschließlich der betroffenen Dateinamen. Stellen Sie diese Dateien aus dem Backup wieder her. Führen Sie sudo zpool clear tank aus, um die Zähler zurückzusetzen, und starten Sie anschließend erneut einen Scrub. Jeder vollständige Scrub erstellt diese Liste neu. Ein Dateiname, der nach einem vollständigen fehlerfreien Scrub fehlt, ist daher tatsächlich nicht mehr vorhanden.

Welcher regelmäßige Scrub-Job läuft auf Ihrem System?

Gehen Sie nicht davon aus, dass es einen solchen Job gibt. Gehen Sie auch nicht davon aus, dass es nur einen gibt. Der Mechanismus unterscheidet sich je nach Plattform und Paket. Das Pool-Format ist überall identisch. Dadurch wird leicht übersehen, dass sich die zugehörigen Werkzeuge unterscheiden. Entscheidend ist hier die Art, wie ZFS unter FreeBSD im Vergleich zu Linux bereitgestellt wird.

Unter FreeBSD gehört der Job zum periodic-System. Setzen Sie diese Werte in /etc/periodic.conf:

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

daily_scrub_zfs_pools ist eine durch Leerzeichen getrennte Liste von Poolnamen. Wenn der Wert leer bleibt, werden alle Pools gescrubbt. daily_scrub_zfs_default_threshold gibt die Anzahl der Tage zwischen Scrubs an, wenn kein Pool-spezifischer Schwellenwert gesetzt ist. Das Handbuch nennt 35 als Standardwert. Der tägliche Job läuft jeden Tag. Er startet einen Scrub erst, wenn der Schwellenwert überschritten wurde.

Unter Linux hängt dies vom ZFS-Paket Ihrer Distribution ab. Einige Systeme enthalten beide Mechanismen gleichzeitig. Es gibt Pool-spezifische systemd-Timer, zfs-scrub-monthly@tank.timer und zfs-scrub-weekly@tank.timer. Diese werden jeweils für einen Pool aktiviert. Debian und Ubuntu liefern außerdem /etc/cron.d/zfsutils-linux aus. Dieses führt ein Skript aus, das am zweiten Sonntag des Monats jeden ONLINE-Pool scrubbiert. Prüfen Sie zuerst, was auf Ihrem System eingerichtet ist:

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

zpool history liefert die verlässliche Antwort. Die Ausgabe erfasst die Scrubs, die der Pool tatsächlich gestartet hat, einschließlich der Zeitpunkte. Zwei Scrubs pro Monat bedeuten, dass beide Mechanismen aktiv sind. Einer davon sollte deaktiviert werden. So aktivieren Sie einen Timer:

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

Freier Speicher ist wichtiger als jede einstellbare Option

Die Dauer eines Scrubs auf einem kleinen Pool hängt davon ab, wie viele Daten zugewiesen sind und wie stark sie verteilt sind. Wenn der Pool vollgeschrieben wird, verschlechtert sich beides.

Die OpenZFS-Empfehlung lautet, mehr als 10% freien Speicher im Pool zu belassen. Darunter unterschreiten Metaslabs, also die Bereiche, in denen der Allocator arbeitet, zunehmend die Schwelle von 4% freiem Speicher. Der Allocator wechselt dann von First-Fit zu Best-Fit. Best-Fit benötigt deutlich mehr CPU-Zeit. Die Schreiblatenz steigt, die Fragmentierung nimmt zu, und der nächste Scrub dauert noch länger, weil dieselbe Datenmenge nun als mehr und kleinere Lesevorgänge verarbeitet wird.

Der erste Ansatzpunkt ist daher keine einstellbare Option. Löschen Sie Daten. Alte Snapshots sind auf einem ZFS-System die häufigste Ursache. Danach folgen Docker-Images und -Layer, die niemand bereinigt hat sowie Kernel-Pakete, die nach Upgrades zurückgeblieben sind. Führen Sie zfs list -o space aus, bevor Sie etwas anderes ändern. Der Befehl trennt den von Snapshots belegten Speicher vom Speicher, den aktive Daten belegen.

Nun kurz zu den Optionen. Unter Linux können Sie die aktuellen Werte auslesen:

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

FreeBSD stellt dieselben Parameter über sysctl bereit. Ermitteln Sie Ihre Werte daher mit sysctl -a | grep scrub. Wenn Sie die Werte erhöhen, wird der Scrub früher abgeschlossen, aber Ihre Anwendung wird langsamer. Wenn Sie sie verringern, gilt das Gegenteil. Bei einem Pool mit einem oder zwei Geräten bietet keine Einstellung beides, weil nur eine Warteschlange aufgeteilt werden kann. Eine Option behebt nur selten ein Designproblem. Wenn ein monatlicher Scrub die Leistung beeinträchtigt, bedeutet das wahrscheinlich, dass der Pool zu voll oder das Gerät zu langsam ist. Eine einstellbare Option verschiebt das Problem dann nur.

Die Scrub-Dauer ist Ihre Vorschau auf das Resilvering

Ein Resilvering durchläuft die Daten auf dieselbe Weise wie ein Scrub: Es liest die belegten Blöcke, überprüft sie und schreibt die fehlenden Blöcke auf das Ersatzgerät. Die Dauer Ihres Scrubs ist daher die verlässlichste realistische Schätzung dafür, wie lange ein Wiederaufbau dauert und wie lange der Pool dabei mit reduzierter Redundanz betrieben wird.

ZFS plant Resilvering-Arbeiten aggressiver als Scrub-Arbeiten. Ein Wiederaufbau ist daher normalerweise schneller abgeschlossen als ein Scrub desselben Pools. Betrachten Sie die Scrub-Dauer als konservative Obergrenze. Wenn der Scrub neun Stunden dauert, sollten Sie für den Wiederaufbau ein Zeitfenster in dieser Größenordnung einplanen. Beachten Sie außerdem, dass der Ausfall eines zweiten Geräts innerhalb dieses Zeitfensters zum Verlust des Pools führt. Das ist ein praktisches Argument für gespiegelte Paare statt einer einzigen breiten raidz-Gruppe, da raidz, das von ZFS anstelle von RAID 5 verwendete Paritätslayout, den Wiederaufbau durch das Lesen aller noch verfügbaren Geräte durchführt.

Bei einem Pool mit nur einem Gerät gibt es kein Resilvering. Fällt das Gerät aus, fällt auch der Pool aus. Ihre Wiederherstellungszeit entspricht dann der Zeit für die Wiederherstellung aus einem Backup. Messen Sie deshalb diese Wiederherstellung. Eine Wiederherstellung, die Sie noch nie durchgeführt haben, ist kein Wiederherstellungsplan.

Was sich ändert, wenn Sie das Laufwerk mieten

Auf einem VPS ist das Blockgerät virtuell. Der Hypervisor stellt ein Volume bereit. Darunter können lokale NVMe-Laufwerke oder ein repliziertes Netzwerk-Volume mit eigener Paritätsverwaltung liegen. Für Scrubs ergeben sich daraus zwei Konsequenzen.

Erstens ist die Redundanz der Plattform für ZFS unsichtbar und kann von ZFS nicht genutzt werden. Wenn die Plattform einen Medienfehler unterhalb Ihres Systems behebt, sieht ZFS das Problem nie. Liefert die Plattform hingegen einen falschen Block an das System, erkennt ZFS ihn, kann ihn aber nicht reparieren. Die korrekte Kopie befindet sich auf der anderen Seite dieser Grenze.

Zweitens können Sie SMART-Daten (Self-Monitoring, Analysis and Reporting Technology) des Geräts unterhalb einer virtuellen Festplatte normalerweise nicht auslesen. Die Frühwarnungen, auf die die Überwachung des Festplattenzustands auf einem VPS angewiesen ist, stehen daher möglicherweise überhaupt nicht zur Verfügung. Der CKSUM-Zähler aus Ihren Scrubs wird zum wichtigsten Signal, das Sie selbst kontrollieren können.

Wenn ZFS Fehler reparieren und nicht nur melden soll, benötigt der Pool mehr als ein Gerät innerhalb derselben Instanz. Das ist eine Planungsentscheidung und keine Tuning-Maßnahme. Mit einem Storage-VPS statt einem regulären VPS erhalten Sie die benötigte Kapazität. Ob Sie dadurch zwei unabhängige Geräte erhalten, hängt jedoch vom Tarif ab. Führen Sie lsblk aus und prüfen Sie dies, bevor Sie einen Mirror aufbauen, der sich letztlich als zwei Partitionen eines einzigen Volumes herausstellt. Wir vermieten Linux- und FreeBSD-Server, aber keine verwaltete ZFS-Appliance. Daher müssen Sie den Scrub-Zeitplan und die Backups selbst ausführen. Der Kompromiss ist klar: vollständige Kontrolle über den Pool und vollständige Verantwortung für seine Wartung.

FAQ

Wie oft sollte ich einen ZFS-Pool auf einem VPS scrubbing?

Monatlich ist für die meisten kleinen Pools angemessen. Das entspricht auch den Voreinstellungen der Pakete: einem Cron-Job am zweiten Sonntag unter Debian und Ubuntu sowie einem Standardschwellenwert von 35 Tagen im periodic-System von FreeBSD. Wöchentliches Scrubbing ist nur sinnvoll, wenn Sie die Dauer eines Scrubs gemessen haben und er auf einem ansonsten nicht ausgelasteten System schnell abgeschlossen wird. Auf einem stark ausgelasteten Pool mit einem oder zwei Geräten verursacht wöchentliches Scrubbing jede Woche echte I/O-Last für Anwendungen und liefert nur wenige Wochen früher eine Warnung.

Ist das Scrubbing eines ZFS-Pools mit nur einem Datenträger sinnlos?

Nein, sofern Sie wissen, welchen Nutzen es hat. Ohne Redundanz erkennt ein Scrub beschädigte Daten, kann sie aber nicht reparieren. Eine Ausnahme sind Metadaten, von denen ZFS standardmäßig eine zusätzliche Kopie vorhält. Sie erhalten eine benannte Liste beschädigter Dateien in zpool status -v. Das geschieht früh genug, um die Dateien wiederherzustellen, solange noch irgendwo eine intakte Kopie vorhanden ist. Die richtige Reaktion sind bessere Backups, da der Scrub genau angibt, welche Datei wiederhergestellt werden muss.

Kann ich einen ZFS-Scrub pausieren und später fortsetzen?

Ja. zpool scrub -p tank pausiert den Scrub. Der Pausenstatus und der Fortschritt werden regelmäßig auf den Datenträger geschrieben. Daher bleibt der Scrub auch nach einem Export oder Reboot pausiert. Führen Sie zpool scrub tank erneut aus, um ihn ab dem letzten Prüfpunkt fortzusetzen. Verwenden Sie dafür nicht zpool scrub -s tank: -s beendet den Scrub, und der nächste Scrub beginnt wieder von vorn.

Warum ist mein ZFS-Scrub so langsam, und kann ich ihn beschleunigen?

Die Dauer eines Scrubs hängt von der belegten Datenmenge und der Fragmentierung ab, nicht von der Datenträgerkapazität. Ein Pool mit mehr als 90% Belegung ist langsam, weil Metaslabs mit weniger als 4% freiem Speicher den Allocator von first-fit auf best-fit umschalten. Die daraus entstehende Fragmentierung führt dazu, dass der Scrub viele kleine Lesevorgänge ausführt. Freigeben von Speicherplatz hilft normalerweise mehr als jede Tunable-Anpassung. Sie können zfs_scrub_min_time_ms oder zfs_vdev_scrub_max_active erhöhen, damit der Scrub einen größeren Anteil der Warteschlange erhält. Bei einem Pool mit einem oder zwei Geräten geht dieser Anteil jedoch direkt zulasten Ihrer Anwendungen.