ZFS für Einsteiger
(ikrima.dev)- Ein Einsteigerleitfaden, der ausgehend von einem ZFS-Ausfall bei FreeNAS Fehlerbehebung, die Konfiguration neuer Volumes und Backup-Strategien behandelt und die beim ersten Betrieb von ZFS nötige Struktur und Befehle in einem durchgehenden Ablauf erklärt
- ZFS bietet Dateisystem und logischen Volume-Manager in einem und nutzt, nachdem es bei Sun Microsystems begann, unter Linux und FreeBSD überwiegend den OpenZFS-Code
- Die Grundstruktur besteht aus vdevs, die physische Datenträger bündeln, daraus aufgebauten Pools, Datasets als Dateisystem-Komponente und Volumes in Form von Blockgeräten; RAIDZ-1/2/3 verkraften jeweils den Ausfall von 1, 2 bzw. 3 Datenträgern
- Im praktischen Betrieb stehen die Befehle
zpool create/status/list/import/export/destroy/scrubundzfs create/mount/list/get/set/snapshot/diff/rollback/send/recv/destroyim Zentrum; um Probleme durch geänderte Gerätenamen zu vermeiden, wird die Verwendung von Device-UUIDs bevorzugt - Snapshots schützen den Zustand zu einem bestimmten Zeitpunkt mit geringem Aufwand und lassen sich per
zfs send/recvauf andere Pools oder Systeme replizieren, sind für sich allein jedoch kaum ein Ersatz für Backups oder DR
Grundkonzepte von ZFS
- ZFS ist sowohl ein lokales Dateisystem wie ext4, NTFS oder exFAT als auch ein logischer Volume-Manager ähnlich LVM unter Linux
- Es wurde von Sun Microsystems entwickelt, und der ZFS-Quellcode war bis zur Übernahme von Sun durch Oracle unter einer Open-Source-Lizenz veröffentlicht
- Da der bereits veröffentlichte Code auf verschiedene Betriebssysteme portiert worden war, entstand später das Projekt OpenZFS, dessen Code heute auf den meisten Unix-artigen Systemen wie Linux und FreeBSD verwendet wird
- Der Text ist aus Sicht von Einsteigern aufbereitet, damit Personen mit erstem Kontakt zu ZFS dessen Struktur und Betriebsbefehle verstehen können
Bestandteile von ZFS
- Ein vdev besteht aus einem oder mehreren physischen Laufwerken und kann neben Festplatten auch Dateien umfassen
- Es kann als Mirror oder RAIDZ aufgebaut werden
- Es gibt 7 vdev-Typen, darunter wichtige Typen wie Hot Spare, L2ARC und ZIL
- Ein Pool besteht aus einem oder mehreren vdevs; üblicherweise werden darin Volumes oder Datasets angelegt
- Beim Erstellen eines Pools mit dem Befehl
zpoolwerden die vdevs direkt mit definiert - Verschiedene vdev-Typen lassen sich kombinieren, um RAIDZ-Stufen aufzubauen
- Beim Erstellen eines Pools mit dem Befehl
- Ein Dataset ist in ZFS die Komponente, die einem Dateisystem entspricht
- Dafür lassen sich Benutzerzugriff, Quota, Komprimierung, Snapshots usw. festlegen
- Ein Volume ist einem Dataset ähnlich, stellt aber ein Blockgerät dar
- Es bietet nur einen Teil der Dataset-Funktionen
- Es ist nützlich, wenn auf ZFS ein anderes Dateisystem betrieben oder ein iSCSI-Extent exportiert werden soll
RAIDZ-Typen
- Dynamic/Simple Stripe, also RAID0, verteilt Daten ohne Parität; fällt ein Gerät aus, gehen alle Daten verloren
- MIRROR, also RAID1, spiegelt Datenträger und wird mit 2 bis 4 oder mehr Laufwerken verwendet
- RAIDZ-1, also RAID5, verteilt Parität zusammen mit den Daten und verkraftet bis zum RAID-Ausfall den Verlust eines physischen Laufwerks
- Für RAIDZ sind mindestens 3 Datenträger erforderlich
- RAIDZ-2, also RAID6, verkraftet den Verlust von bis zu 2 physischen Laufwerken
- Für RAIDZ-2 sind mindestens 4 Datenträger erforderlich
- RAIDZ-3 verkraftet den Verlust von bis zu 3 physischen Laufwerken
- Mindestens 4 Datenträger sind erforderlich, sinnvoll ist es jedoch meist erst ab 5 oder mehr
Pool erstellen und Status prüfen
- Ein ZFS-Pool wird im Format
zpool create [pool] [devices]erstellt- Beispiel für einen Pool mit einer einzelnen Platte:
zpool create tank /dev/sdb - Beispiel für einen Stripe mit 3 Platten:
zpool create tank /dev/sdb /dev/sdc /dev/sdd - Beispiel für einen Mirror mit 2 Platten:
zpool create tank mirror sdb sdc - Beispiel für einen RAIDZ-Pool:
zpool create tank raidz sdb sdc sdd - RAIDZ2/3 können im Format
zpool create [pool name] raidz[1,2,3] [devices]erstellt werden
- Beispiel für einen Pool mit einer einzelnen Platte:
- Beim Erstellen des Pools kann mit dem Flag
-mder standardmäßige Mount-Point festgelegt werden- Beispiel:
zpool create tank -m /mnt/tank mirror sdb sdc
- Beispiel:
- In den Beispielen werden Gerätenamen in der Form
/dev/sdxverwendet, um Boot-Probleme durch geänderte Gerätenamen zu vermeiden, wird jedoch die Nutzung von Device-UUIDs bevorzugt zpool statusist der grundlegende Befehl zum Prüfen des Pool-Statusstatezeigt an, ob der Pool online iststatuszeigt zusätzliche Informationen zum Pool anactionzeigt nötige Folgeschritte anscanzeigt den Fortschritt eines Scrubs oder den Status des letzten Scrubs anerrorszeigt an, ob es Probleme im Pool gibt
zpool listzeigt Details wie Größe, Belegung, freien Speicher, Fragmentation, Capacity, Dedup und Health des Poolszpool historyzeigt die Befehlschronik der seit der Erstellung am Pool vorgenommenen Konfigurationsänderungen
Pool importieren, exportieren, löschen und scrubben
- Nach der Erstellung wird ein Pool normalerweise automatisch importiert und gemountet, bei der Fehlerbehebung oder nach einer System-Neuinstallation kann jedoch ein manueller Import nötig sein
- Wird
zpool importohne Pool-Namen ausgeführt, zeigt es die Liste importierbarer Pools an- Wenn kein importierbarer Pool vorhanden ist, erscheint
no pools available to import - Wird ein Pool-Name angegeben, wird dieser Pool importiert; der Import-Befehl mountet den Pool auch
zpool import -aimportiert alle importierbaren Pools
- Wenn kein importierbarer Pool vorhanden ist, erscheint
- Mit
-R, etwa inzpool import -R /mnt/tank2 tank, wird unter einem alternate root gemountet- Dabei handelt es sich nicht um den Mount-Pfad des Pools selbst, sondern um einen alternativen Root-Ordner
zpool export [pool name]ist das Gegenstück zu Import und versucht nach dem Unmounten der im Pool eingehängten Dateisysteme den Export- Falls das Unmounten des Dateisystems fehlschlägt, kann mit
-fein erzwungenes Unmounten versucht werden - Wenn ein verwendetes ZFS-Volume vorhanden ist, schlägt der Export selbst mit
-ffehl
- Falls das Unmounten des Dateisystems fehlschlägt, kann mit
zpool destroylöscht den Pool samt untergeordneten Datasets oder Volumes- Dabei werden auch alle Daten und Snapshots gelöscht, daher ist Vorsicht nötig
- Ein ZFS-Scrub prüft alle Blöcke eines Pools, indem sie mit bekannten Checksummen verglichen werden, um die Datenintegrität zu verifizieren
- Bei vdevs mit Parität werden beschädigte Daten anhand der Daten auf intakten Laufwerken wiederhergestellt
- Um den Systemzustand zu erhalten, sollte ein Scrub regelmäßig geplant ausgeführt werden
- Start:
zpool scrub [pool] - Status prüfen: Bereich
scaninzpool status - Stoppen:
zpool scrub -s [pool]
Dataset erstellen und mounten
zfs createerzeugt ein neues Dateisystem oder Volume; hier liegt der Fokus eher auf Datasets als auf Volumeszfs create tank/dataset1erstelltdataset1untertank- Das Dataset
tankwird beimzpool createautomatisch angelegt
- Das Dataset
zfs create -perstellt ähnlich wiemkdir -pauch fehlende übergeordnete Datasets- Fehlt ein übergeordnetes Dataset, schlägt ein normales
zfs createfehl
- Fehlt ein übergeordnetes Dataset, schlägt ein normales
- Wird
zfs mountohne Argumente ausgeführt, zeigt es die aktuell gemounteten ZFS-Dateisysteme und ihre Mount-Points an- Diese Ausgabe enthält keine Child-Datasets
zfs mount [pool|dataset]mountet das angegebene Dateisystemzfs mount -amountet alle Dateisysteme
- Child-Datasets können auch ohne ihr Parent-Dataset gemountet werden
- In diesem Fall werden die im Betriebssystem-Dateisystem erforderlichen Pfade erstellt
- Wenn später das Parent-Dataset gemountet werden soll, kann wegen der erzeugten Verzeichnisse der Fehler
directory is not emptyauftreten
zfs unmount [dataset]unmountet das angegebene Dataset
Dataset anzeigen und Eigenschaften setzen
zfs list [dataset name]zeigt Informationen zum angegebenen Dataset an- Statt des Dataset-Namens kann auch der Mount-Point als Argument übergeben werden
- Wird
zfs listohne Dataset-Namen ausgeführt, zeigt es rekursiv alle Datasets des Systems an - Wird beim Angeben eines Dataset-Namens das Flag
-rverwendet, kann alles unterhalb dieses Datasets rekursiv angezeigt werden - ZFS-Properties steuern das Verhalten von Dateisystem, Volume, Snapshot und Clone
- Sie können Mount-Optionen ähneln
zfs get all [dataset]zeigt alle Properties eines Datasets an- Der Wert einer bestimmten Property lässt sich etwa mit
zfs get compression tankprüfen - Zum Setzen von Properties wird
zfs setverwendet- Beispiel:
zfs set compression=lz4 tank - Danach kann mit
zfs get compression tankbestätigt werden, dasscompressionauflz4geändert wurde
- Beispiel:
Funktionsweise und Nutzung von Snapshots
- Ein Snapshot speichert den Zustand eines Dateisystems zu einem bestimmten Zeitpunkt, kopiert dabei aber keine Dateien
- Ein Snapshot markiert vorhandene Daten als schreibgeschützt, und auch wenn danach neue Daten zum Dateisystem hinzukommen, bleiben die durch den Snapshot geschützten vorhandenen Datenblöcke unverändert
- Der beispielhafte Ablauf ist wie folgt
- In einem Dateisystem mit vorhandenen Daten A wird Snapshot 1 erstellt
- Danach werden Daten B hinzugefügt und Snapshot 2 erstellt
- Danach werden Daten C hinzugefügt
- Snapshot 1 schützt Daten A, Snapshot 2 schützt Daten A und Daten B
- Selbst wenn Snapshot 1 gelöscht wird, bleiben Daten A weiterhin durch Snapshot 2 geschützt
- Der durch einen Snapshot belegte Datenumfang ist sehr klein
- Denn statt Dateien zu kopieren, wird nur der oberste Metadatenblock des Dateisystems aufgezeichnet, der zu diesem Snapshot gehört
- Snapshots sind nützlich für Softwaretests oder als Failsafe vor Upgrades
- Snapshots allein sollten nicht als Backup- oder DR-Lösung betrachtet werden
Snapshot-Befehle
- Snapshots werden im Format
zfs snapshot [pool/dataset@snapshot_name]erstellt- Beispiel:
zfs snapshot tank/dataset1@snapshot1
- Beispiel:
- Die Snapshot-Liste lässt sich mit
zfs list -t snapshotanzeigen - Wenn mehrere Child-Datasets vorhanden sind, kann auf dem Top-Level-Dataset ein Snapshot erstellt oder mit dem Flag
-rein rekursiver Snapshot angelegt werden- Beispiel für einen normalen Snapshot:
zfs snapshot tank@snapshot-master - Beispiel für einen rekursiven Snapshot:
zfs snapshot -r tank@recursive
- Beispiel für einen normalen Snapshot:
zfs diff [older snapshot] [newer snapshot]vergleicht die Unterschiede zwischen Snapshots- In der Ausgabe lassen sich hinzugefügte Dateien und geänderte Pfade erkennen
- Die Wiederherstellung eines Snapshots erfolgt mit
zfs rollback [pool/dataset@snapshot_name]- Bei einem Rollback werden Dateien gelöscht, die nach dem Snapshot erstellt wurden
- Auch neuere Snapshots werden gelöscht; in diesem Fall kann die Verwendung der Option
-rverlangt werden
ZFS send/recv und Replikation
- ZFS send kann Snapshots als Datenstrom übertragen
- Snapshots und Datasets lassen sich in Dateien, in andere Pools oder per SSH auf andere Systeme replizieren
- In den Beispielen werden zwei Pools mit den Namen
tankundbackupverwendet- Im Dataset
tank/Moviesliegen 1.50G Daten - Vor der Übertragung wird mit
zfs snapshot tank/Movies@$(date '+%Y-%m-%d_%H-%M')ein Snapshot erstellt - Mit
zfs send tank/Movies@2020-11-03_15-29 | zfs recv backup/Movieswird der Snapshot in den Backup-Pool übertragen
- Im Dataset
- Nach der Übertragung sind in
zfs listsowohlbackup/Moviesals auchtank/Moviessichtbar, und inzfs list -t snapshotsind die Snapshots auf beiden Seiten zu sehen zfs sendist eine Funktion mit vielen Optionen und Einsatzszenarien; zusammen mit RAIDZ und Snapshots kann sie das Dateisystem robuster machen
Datasets und Snapshots löschen
- Ein Dataset wird im Format
zfs destroy [pool/dataset]gelöscht- Das Flag
-rkann ebenfalls verwendet werden
- Das Flag
- Auch für das Löschen eines Snapshots wird
zfs destroy [pool/dataset@snapshot_name]verwendet- Auch beim Löschen von Snapshots kann das Flag
-rverwendet werden
- Auch beim Löschen von Snapshots kann das Flag
- ZFS bietet noch viele weitere Funktionen, aber dieses Material ist eher ein Einstiegspunkt zum Erlernen der Grundkonzepte und Befehle
1 Kommentare
Meinungen auf Hacker News
Zum Beispiel sollte man beim Erstellen eines Pools einfach vernünftige Defaults wie
ashift=12,lz4-Kompression,xattr=sa,acltype=posixaclundatime=offverwenden können, und Verschlüsselung sollte statt vieler Optionen nur Ein/Aus sein.Er sollte Verschlüsselungsschlüssel erzeugen, einen
systemd-Dienst einrichten, der den Pool beim Booten entschlüsselt, und zum Backup der Schlüssel anleiten.zfs listsollte anzeigen, ob ein Dataset gemountet ist, ob es verschlüsselt ist und ob der Schlüssel geladen ist.Rekursive Datasets sollte man abschaffen und Pool und Dataset statt mit
{pool}/{dataset}klar mit{pool}:{dataset}voneinander trennen. Auch Pool- oder Snapshot-Namen sollte man nicht selbst vergeben müssen; stattdessen wären automatisch vergebene Regeln wie{hostname}-[A-Z]oder{pool name}_{datetime created}sowie numerische Kurznamen sinnvoll.Beim Erstellen eines Pools sollte man keine Disk-IDs direkt eingeben müssen; man sollte ihn mit
/dev/sda,/dev/sdbanlegen können, und ZFS sollte Metadaten auf den Disks speichern, damit es auch nach geänderter Laufwerksreihenfolge nicht durcheinanderkommt.Fortschritt sollte immer mit
pvangezeigt werden, und wöchentliche Scrubs sowie stündliche/tägliche/wöchentliche/monatliche Snapshots samt Aufräumen sollten automatisch eingerichtet werden.Wenn man auf eine Disk ohne Pool sendet, sollte nach Bestätigung ein Single-Disk-Pool mit denselben Einstellungen wie der sendende Pool erstellt werden, und
zpoolundzfssollten zu einem einzigen Kommando zusammengeführt werden.Beim Senden verschlüsselter Datasets sollte automatisch
--rawverwendet werden, als Send-Default sollte--replicategelten, und wenn möglich sollte-Igenutzt werden. Snapshot-Dateisysteme sollten nicht in versteckten Verzeichnissen verborgen werden; außerdem braucht es eine einfache Möglichkeit, Snapshot-Datasets zu mounten und zu durchsuchen.ashift=12oder die Syntax{pool}:{dataset}kann ich nachvollziehen, aber das jetzt noch zu ändern wirkt schwierig, und manche Vorschläge könnten unbekannte Use Cases kaputtmachen.Pools nach dem Hostnamen zu benennen passt nicht zu SAN-Pools, die von mehreren Hosts importiert werden können.
Wöchentliche Scrubs, periodische Snapshots und periodisches Aufräumen sehe ich als Aufgabe des Betriebssystem-Schedulers.
zpoolundzfszusammenzuführen wäre zwar möglich, aber am Ende hätte man dann etwas wiezfs -pool XXXX,zfs -volume XXXX– ich sehe nicht, warum das nötig wäre.Rekursive Datasets sind in der Praxis manchmal nützlich. Andererseits stimme ich völlig zu, dass
zfs listanzeigen sollte, ob etwas gemountet ist, ob es verschlüsselt ist und ob der Schlüssel geladen ist.Der Punkt, keine Disk-IDs eingeben zu müssen, ist unklar. Man kann Disks über ID, WWN, Label,
sdXusw. angeben, aber irgendwie muss man ZFS trotzdem mitteilen, welche Disk verwendet werden soll.Die Funktion, Metadaten auf der Disk zu speichern, sodass sie auch nach geänderter Reihenfolge gefunden wird, gibt es bereits. Wenn man ein paar Laufwerke umsteckt und den Pool importiert, werden sie gefunden.
Einige Vorschläge wären als Defaults in Ordnung, aber bei manchen scheint die eigene Nutzung und der Bedarf außerhalb davon nicht ausreichend bedacht zu sein. ZFS richtet sich an sehr viel mehr Anwender.
/dev/sda,/dev/sdbzu erstellen und dann zu sagen, ZFS komme durcheinander, ist ehrlich gesagt weniger ein ZFS-Problem als eher ein Problem eines Nutzers, der es nicht zeitgemäß verwendet.Unter Linux gibt es schon seit ziemlich langer Zeit vollständige Referenzen wie
/dev/disk/by-id/ata-$manufactuer-$serial-$whatever. Beim Erstellen eines Pools sollte man solche Pfade verwenden.{pool}:{dataset}sein sollte.Wenn du Snapshot-Namen nicht selbst vergeben willst, könnte mein kleines Tool https://github.com/rollcat/zfs-autosnap passen.
Wenn man
zfs-autosnap snapstündlich in cron einträgt undzfs-autosnap gctäglich, rotiert es die Snapshot-Historie entsprechend der Aufbewahrungsrichtlinie.Einen einfachen ZFS-Kommando-Wrapper zu schreiben ist nicht schwer; du kannst also meinen Code nehmen und dir dein eigenes Tool bauen.
Auch bei der Arbeit habe ich mehrere Skripte geschrieben, die ZFS-Arrays passend zu der jeweils vorgesehenen Deployment-Form erstellen. Darin enthalten waren das Erzeugen eines LUKS-verschlüsselten Volumes für zvols, die Standardisierung von Namensregeln sowie Defaults wie
ashift=12undlz4-Kompression.Das war lange bevor ZFS eigene Verschlüsselung bekam, und da die heutige Methode für uns weiterhin funktioniert, habe ich die Skripte nicht aktualisiert, um ZFS-Verschlüsselung zu unterstützen.
Inzwischen erinnere ich mich nicht mehr an viele Flags, aber die Skripte dienen als Dokumentation, und die anderen im Team müssen nur
make-zfs-big-mirrorodermake-big-zfs-undundant-raid0ausführen.Falls ich eines Tages mehr als 20-mal im Jahr Systeme provisionieren muss, kann selbst das noch in die Provisionierung automatisiert werden.
Keine Pool-Namen vergeben zu wollen ergibt keinen Sinn. Man erstellt Pools nicht so häufig, also vergib einfach einen Namen.
Wenn du Snapshot-Namen nicht selbst vergeben willst, kannst du
httmundzfs allowverwenden.httm -S .erzeugt zum Beispiel einen Snapshot wierpool/ROOT/ubuntu_tiebek@snap_2022-12-14-12:31:41_httmSnapFileMount.zfsundzpoolsind jeweils hervorragende Unix-Kommandos mit mehreren Unterbefehlen. Ich halte es für eine sehr kluge Entscheidung der ZFS-Designer, kein komplexeres einzelnes Verwaltungskommando gebaut zu haben.Snapshot-Datasets explizit zu mounten und zu durchsuchen ist mit
zfs mountebenfalls leicht möglich. Man sollte aber auch anerkennen, dass eine stabile virtuelle Schnittstelle die Suche über alle Dateiversionen hinweg erleichtert, und dass dies bei btrfs und anderen deutlich schwieriger ist.httmist ebenfalls einen Blick wert.[0]: https://kimono-koans.github.io/opinionated-guide/#dynamic-sn...
Es gibt noch weitere nützliche Dinge in ZFS. Es ist gut, den Unterschied zwischen
zpool-attach(8)undzpool-replace(8)zu kennen, undzfs list -t all -o spacezeigt, wofür Speicherplatz verwendet wird.Zum Schutz des Betriebssystems vor größeren Änderungen oder Upgrades sind ZFS Boot Environments das beste Feature. Als Einstieg kann https://is.gd/BECTL hilfreich sein.
zpool history poolnamezeigt die gesamte Pool-Konfiguration und Änderungshistorie. Dort werden zum Beispiel Änderungen wiezpool create,autotrim=on,atime=off,compression=zstdoderrecordsize=1mprotokolliert.Im Guide fehlt auch eine wichtige Information: Bei einem 3-way Mirror bleiben die Daten erhalten, selbst wenn 2 von 3 Platten ausfallen; bei einem 4-way Mirror bleiben sie erhalten, wenn 3 von 4 ausfallen; und bei einem N-way Mirror bleiben die Daten erhalten, solange von N Platten höchstens N-1 ausfallen.
Das ist nützlich, wenn die Daten das Wichtigste sind, aber nicht viele Slots oder Platten vorhanden sind.
Ich betreibe seit Jahren große PostgreSQL-Datenbanken im Multi-TB-Bereich auf ZFS. Dank ZFS sind Backups, das Erstellen von Testumgebungen auf Basis alter Snapshots und das Sparen von Plattenplatz durch integrierte Kompression sehr einfach geworden.
Wer Interesse hat, kann unsere Erfahrungen unter https://lackofimagination.org/2022/04/our-experience-with-po... nachlesen.
Beim Einstieg in ZFS waren für mich das ZFS Handbook von FreeBSD und die Artikel von Aaron Toponce am hilfreichsten.
[0] https://docs.freebsd.org/en/books/handbook/zfs/
1 https://pthree.org/2012/04/17/install-zfs-on-debian-gnulinux...
Ich habe FreeBSD auf einem alten HP Microserver mit 1 GB ECC-RAM installiert, der noch herumstand, und hatte auch fünf alte 500-GB-Festplatten. Anhand des FreeBSD Handbook habe ich sie als 5x-Mirror eingerichtet. Es war mein erstes Mal mit FreeBSD, und es ging sehr reibungslos.
Vor Kurzem habe ich viel Infrastruktur neu aufgebaut, hauptsächlich LAMP-Server, und mich entschieden, alles für effiziente Backup-Replikation und Verschlüsselung auf ZFS unter Linux aufzusetzen.
Ich nutzte ZFS zusammen mit
rsyncschon lange für Backups und war daher ziemlich vertraut damit; am Ende hat es gut funktioniert. Aber der Versuch, es wirklich sauber zu machen, kostete deutlich mehr Zeit als erwartet. Besonders zu Datenbanken und Replikation findet man im Web viele falsche Ratschläge.Bei Datenbanken sollte man mindestens grundlegendes Tuning wie Blockgrößen-Ausrichtung vornehmen. Zu mariadb/InnoDB war das Material von Let’s Encrypt unter https://github.com/letsencrypt/openzfs-nvme-databases mit Abstand am besten. Es ist sehr wertvoll, weil jeder Punkt begründet und mehrere Quellen zitiert werden.
Wenn man weiter im Web sucht, findet man endlos widersprüchliche Ratschläge, Anekdoten und Mythen, oft unvollständig und mit unbelegten Theorien. Am Ende muss man selbst testen, verstehen, was man einstellt, und es ist auch in Ordnung, sich bewusst gegen ein Tuning zu entscheiden.
Für Replikation empfehle ich wirklich die Manpages. ZFS stellt robuste Replikationswerkzeuge bereit, aber sie sind so allgemein gehalten, dass sie sich wie Git-Plumbing-Kommandos anfühlen. Da ZFS nicht annimmt, dass man SSH verwendet, muss man die Teile selbst zusammenstecken; und wenn man automatisieren will, muss man auch Randbedingungen bedenken, was anfangs einschüchternd wirkt.
Deshalb greifen viele zu Tools wie
syncoid, aber an Replikationsskripten dersyncoid-Art gab es etwas Schreckliches: Sie verwenden nicht densend --replication-Modus von ZFS, sondern implementieren ihn in Perl unvollständig neu, mit dem Argument, das sei flexibler.Beim ersten Testen und anschließenden Restore neu anzufangen und dann zu sehen, dass alle Encryption Roots kaputt sind und Dataset-Properties nicht vollständig automatisch synchronisiert werden, macht einen wahnsinnig. Wenn man einfach die eingebaute rekursive Replikationsoption verwendet, erledigt ZFS das.
Wenn man sich vornimmt, selbst ein Skript zu schreiben, ist es nicht schwer. Man muss es schlicht halten und nicht wie
syncoidjede Menge unnötige Dinge in die Pipeline stopfen. In realen Tests bremsen solche Dinge sogar. Den Fortschritt sieht man mitpv, und dann schiebt man es einfach durch; das läuft schnell.Vielleicht veröffentliche ich irgendwann mein Replikationsskript. Ich habe den Eindruck, dass es kaum gute Referenzskripte gibt, die die Grundlagen abdecken, ohne Replikation schlecht neu zu implementieren.
io_capacityundio_capacity_max, aber wenn man in der MySQL-Dokumentation nachliest, welche Rolle diese Parameter tatsächlich spielen, sind sie leider nicht besonders nützlich.Diese Werte steuern Hintergrund-I/O wie das Zusammenführen des Change Buffers und können I/O von Hauptprozessen abziehen, die tatsächlich Arbeit zu erledigen haben.
Aus Erfahrung mit einer recht ausgelasteten MySQL-DB mit 120K QPS musste ich keinen der beiden Werte anfassen. Wenn man meint, das sei nötig, sollte man zuerst überwachen, wie lange es dauert, bis das Redo Log voll läuft, und wie hoch der Anteil schmutziger Seiten im Buffer Pool ist. Wahrscheinlich ist es besser, andere Parameter anzupassen.
[0] https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.ht...
Auf einer bestimmten Ebene kann das effizienter sein, aber meiner Erfahrung nach verschlechtert es die Kompressionsrate deutlich.
Als interessanter Nebeneffekt kann sich, je nach Workload, der Durchsatz sogar verschlechtern, wenn die Plattenbandbreite der Engpass ist. Durch Kompression kann man schneller lesen und schreiben, als die physische Platte eigentlich leisten würde; wenn man die Kompression ruiniert, kann das die Lese-/Schreibbandbreite negativ beeinflussen.
Ich nutze ZFS unter Linux seit ein paar Jahren, und insgesamt lief es reibungslos.
Das Einzige, was mich wirklich überrascht hat, war, dass der Standardwert für volblocksize für die meisten RAIDZ-Konfigurationen ziemlich ungünstig ist. Man muss den Wert erhöhen, wenn man nicht 50 % des rohen Plattenplatzes verlieren will.
Die relevanten Beiträge sind diese:
https://jro.io/nas/#overhead
https://openzfs.github.io/openzfs-docs/Basic%20Concepts/RAID...
https://www.delphix.com/blog/zfs-raidz-stripe-width-or-how-i...
Am Ende bin ich sogar bei einer der ZFS-Tabellen gelandet:
ZFS overhead calc.xlsx
https://docs.google.com/spreadsheets/d/1tf4qx1aMJp8Lo_R6gpT6...
RAID-Z parity cost
https://docs.google.com/spreadsheets/d/1pdu_X2tR4ztF6_HLtJ-D...
Als ich jünger und noch dümmer war, las ich viele Beiträge von Enthusiasten darüber, wie großartig Open-Source-NAS-OS, vermutlich FreeNAS, und ZFS seien. Ich kaufte bei eBay einen gebrauchten HP MicroServer mit sehr niedriger Ausstattung und stürzte mich hinein, ohne wirklich zu wissen, was ich tat.
Ich stellte ein paar Fragen in den Community-Foren, aber die meisten Antworten lauteten: „Hast du die Doku gelesen?“ und „Hast du genug RAM?“
Diese Doku bestand aus schwer lesbaren PowerPoint-Folien, in einem leicht missionarischen Ton, mit vielen vorausgesetzten Kenntnissen, und sie wurde auch nicht regelmäßig aktualisiert. Wie viel RAM man brauchte, blieb ebenfalls vage; der Schwerpunkt lag einfach darauf, so viel wie möglich einzubauen.
Am Ende ignorierte ich alle Warnsignale in Bezug auf die Technik, den Hype und meinen eigenen Wissensstand und verlor eine Menge Daten. Ich habe viel gelernt.
Das Dateisystem ist deutlich stabiler geworden, und auch die Dokumentation ist meiner Meinung nach klarer geworden.
Trotzdem ist es mächtiger und fortgeschrittener als ein traditionelles Journaling-Dateisystem wie ext3, und damit gibt es auch mehr Möglichkeiten, sich selbst ins Knie zu schießen.
Um noch ein paar Dinge für später festzuhalten: Sämtliche Redundanz in ZFS liegt auf der vdev-Ebene. Ein zpool besteht aus einem oder mehreren vdevs, und egal in welchem Fall: Verliert man auch nur ein vdev innerhalb eines zpool, ist der zpool dauerhaft zerstört.
Historisch ließ sich RAIDZ, also Parity-RAID, nicht durch Hinzufügen von Festplatten erweitern. Die einzige Möglichkeit, ein RAIDZ zu vergrößern, bestand darin, jede Platte im Array einzeln durch eine größere zu ersetzen und zu hoffen, dass während des Rebuilds keine Platte ausfällt.
Nach sehr laienhafter Einschätzung würde ich RAIDZ nur bei einer großen Anzahl von Platten in Betracht ziehen, etwa RAIDZ2 oder RAIDZ3. Bei n<=6 und wenn das Budget es zulässt, würde ich mehrere Mirror-vdevs verwenden. In einer Produktionsumgebung sollte man die Lese-/Schreib-Performance-Kennzahlen der verschiedenen RAID-Varianten genauer untersuchen.
RAIDZ1 würde ich nur empfehlen, wenn es ein vollständiges Vor-Ort-Backup gibt und man den eigenen Fähigkeiten sowie dem Monitoring ziemlich vertraut.
In meinem Fall habe ich einen Pool mit 3x3 Laufwerken und sende Snapshots an ein Backup-Ziel ein paar Höheneinheiten weiter unten im Rack. Dieses Backup-Ziel wacht täglich auf, hat einen Pool mit 3x4 Laufwerken und ist ebenfalls RAIDZ1.
Wenn im NAS eine Platte ausfällt, ist mein Plan, das Backup sofort zu starten, die Snapshots entgegenzunehmen und dann die Platte zu ersetzen. So lässt sich die Wahrscheinlichkeit minimieren, dass während des Resilverings ein zweites Laufwerk ausfällt und Daten verloren gehen.
Wirklich wichtige Daten liegen natürlich auch extern.
Ich habe ein ZFS-Problem, das ich nicht verstehe. Bei einem bestimmten zpool gibt
zpool statuseine Liste erkannter Fehler aus, aber sie erscheinen nicht bei Dateien, sondern immer nur bei Snapshots und vermutlich bei hexadezimalen Einträgen, die wie gelöschte Snapshots wirken.Wenn ich die als fehlerhaft markierten Snapshots lösche und
zpool scrubzweimal laufen lasse, verschwinden die Fehler, und der Scrub findet ebenfalls keine Fehler.zpool statushat noch nie bei irgendeinem Gerät Fehler angezeigt.Es gibt keine Fehler in Dateien, keine Fehler auf Geräten, und auch beim Scrub werden keine Fehler erkannt, aber im laufenden Betrieb tauchen pro Tag ein Dutzend neue „Fehler“ in
zpool statusauf. Ich verstehe nicht, wie so etwas passieren kann.Ersteres sieht seltsam aus, ist aber das normale Web-Frontend der Mailingliste.
Man kann sie nicht verschieben oder ändern, nur löschen. Ich habe keinerlei Anhaltspunkt, warum diese Dateien beschädigt werden. Zum Glück waren es alles große Linux-ISOs, also war es nicht kritisch.