====== ZFS ====== ZFS ist ein Dateisystem, das sich sehr gut für große Datenmengen eignet. Es sollten aber auch entsprechende Hardwarevoraussetzungen vorhanden sein. ===== Informationen ===== Eine Seite, die ZFS gut erklärt ist [[https://pthree.org/2012/04/17/install-zfs-on-debian-gnulinux/|pthree.org]]. ===== ZFS on Linux ===== Ich verwende ZFS on Linux auf einem Debian-Server. Homepage von [[http://zfsonlinux.org/|ZFS on Linux]] ===== zpool erstellen ===== Es sollte immer die ID einer Festplatte / Partition verwendet werden, da sich die Laufwerksbuchstaben (/dev/sda, /dev/sdb, etc.) bei einem Neustart des Systems ändern können. Die Option ''-o ashift=12'' sollte bei Festplatten mit 4KB-Sektoren unbedingt verwendet werden, um die volle Performance zu erreichen. Diese sorgt für ein korrektes Alignment der Partitionen. ==== zpool mit einem zmirror (RAID1) erstellen ==== zpool create -o ashift=12 home mirror /dev/disk/by-id/ID_DER_FESTPLATTE1 /dev/disk/by-id/ID_DER_FESTPLATTE2 Im Beispiel ist ''home'' der Name des zu erstellenden zpools. Dieser wird dann direkt unter ''/'' eingebunden. Es kann ein beliebiger Name für den Pool vergeben werden.\\ ''mirror'' gibt an, dass ein Pool mit gespiegelten Festplatten erstellt werden soll. Am Ende werden die Pfade zu den Festplatten angegeben. Es sind alle Festplatten anzugeben, die für den Spiegel verwendet werden sollen. Es sind auch Partitionen möglich. Wenn eine ganze Festplatte angegeben wird, erstellt zfs die Partitionen selbstständig. ==== zpool mit einem raidz erstellen ==== zpool create -o ashift=12 data raidz2 /dev/disk/by-id/ID_DER_FESTPLATTE1 /dev/disk/by-id/ID_DER_FESTPLATTE2 /dev/disk/by-id/ID_DER_FESTPLATTE3 /dev/disk/by-id/ID_DER_FESTPLATTE4 usw. Im Beispiel wird ein raidz2 erstellt. Dies entspricht etwa RAID6. D.h. es dürfen bis zu zwei beliebige Festplatten ausfallen, ohne dass es zu Datenverlust kommt. weitere mögliche raidz-Level sind raidz1 für einfache Parität (RAID5), und raidz3 mit dreifacher Parität (Es dürfen bis zu drei Festplatten ausfallen).\\ ''data'' ist der Name des Pools. Er wird direkt unter ''/'' eingebunden. Ein Eintrag in ''/etc/fstab'' ist nicht notwendig! ===== weitere sinnvolle Optionen ===== * Autoexpand einschalten: Wenn man den Pool mal durch größere Festplatten erweitern möchte, muss diese Option vor dem Tausch der ersten Festplatte gesetzt werden. Dadurch steht die volle Größe der neuen Festplatten zur Verfügung, sobald alle Festplatten getauscht wurden. ''pool'' ist der Name des Pools. zpool set autoexpand=on pool * Kompression einschalten! Dateien werden dann komprimiert gespeichert, was Speicherplatz spart. lz4 ist eine sehr schnelle Kompression, sodass kaum CPU-Leistung dafür benötigt wird. zfs set compression=lz4 pool ===== ZIL (Log) hinzufügen ===== zpool add -o ashift=12 pool log mirror ID_SSD_1 ID_SSD_2 Fügt dem Pool ''pool'' einen ZIL-log Spiegel hinzu. Durch den ZIL werden Synchrone Schreibzugriife beschleunigt. NFS profitiert hiervon massiv! Für den ZIL wird nur wenig Speicher benötigt. Es genügt z.B. eine kleine Partition auf einer SSD. Der Restliche Speicherplatz der SSD kann gut als L2ARC verwendet werden. ===== L2ARC (Cache) hinzufügen ===== zpool add -o ashift=12 pool cache ID_SSD Fügt dem Pool ''pool'' einen Cache hinzu. Häufige Lesezugriffe auf die gleichen Daten profitieren vom Cache. Als Cache sollte eine SSD verwendet werden. Man kann z.B. auch eine SSD entsprechend partitionieren und eine kleine Partition für den ZIL verwenden. ===== Special Device hinzufügen ===== zpool add -o ashift=12 pool special mirror ID_SSD1 ID_SSD2 Auf dem Special-Device werden die Metadaten gespeichert. Dadurch ggf. enormer Performance-gewinn. Das Redundanzlevel sollte dem des Pools entsprechen, da beim Ausfall der komplette Pool verloren ist. Die nötige Kapazität der SSD hängt vom Datenbestand ab. Falls die SSD voll ist, werden weitere Metadaten auf den Haupt-Pool geschrieben. ==== kleine Blöcke auf Special Device auslagern ==== Um die Performance beim schreiben/lesen von (sehr) kleinen Dateien zu verbessern, können kleine Datenblöcke auf dem Special Device, statt auf den normalen Datasets gespeichert werden. Dazu gibt man die maximale Größe von Blöcken an, die auf dem Special Device gespeichert werden sollen. Blöcke, die größer als die angegebene Größe sind, werden auf den regulären Datasets gespeichert. Datenblöcke mit max. der angegebenen Größe werden auf dem Special Device gespeichert. zfs set special_small_blocks=16K pool Ab jetzt werden Blöcke bis 16kB auf dem Special Device gespeichert. Es ist möglich, diese Option für jedes Dataset separat und unabhängig einzustellen. **ACHTUNG:** Die angegebene Blockgröße ''special_small_blocks'' solte immer kleiner sein, als die Blockgröße des Pools (standard: 128K)! Wenn ''special_small_blocks'' gleich der Blockgröße des Pools gesetzt wird, wird ALLES ins Special Device geschrieben! ===== TRIM für SSDs ===== Wenn man einen SSD-Pool hat, kann es sinnvoll sein, TRIM zu aktivieren. Dies kann die Schreibperformance verbessern. ''autotrim'' meldet der SSD nach einem Löschvorgang automatisch nicht mehr benötigte Blöcke. Dies ist ein schneller Vorgang, weil nur Blöcke gemeldet werden, die gerade gelöscht wurden. zpool set autotrim=on pool Einstellung kann überprüft werden mit: zpool get autotrim Auf Debian gibt es noch die Option ''periodic-trim''. Dies kann aktiviert werden mit zfs set org.debian:periodic-trim=enable pool Wenn man diese Option aktiviert, wird der Pool am ersten Sonntag im Monat vollständig getrimmt. Die beiden Optionen ''autotrim'' und ''periodic-trim'' dürfen beide zusammen aktiviert werden. Dann werden die SSDs nach jedem löschen schnell getrimmt, und jeden Monat noch mal vollständig. Es ist auch möglich einen Pool manuell zu trimmen. Dazu führt man folgendes Kommando aus. zpool trim pool ===== Datasets erstellen ===== Es ist empfehlenswert direkt in den Pools keine Daten zu speichern, da sonst einige tolle Funktionen von ZFS nicht sinnvoll genutzt werden können. Daher sollte man sogenannte Datasets anlegen. Diese stellen quasi Unterdateisysteme dar. Es kann z.B. auch sinnvoll sein für jeden Benutzer ein eigenes Dataset unter ''/home'' zu erstellen. Dadurch ist es auch sehr einfach möglich, für jeden Benutzer ein individuelles Quota einzurichten. zfs create home/benutzer1 Erstellt ein Dataset ''benutzer1'' im Pool ''home''.\\ Eine Übersicht aller ZFS-Dateisysteme anzeigen: zfs list ==== Datasets in anderes Verzeichnis mounten ==== Datasets können einfach an einen beliebigen Ort im Verzeichnisbaum gemountet werden. Dafür gibt es die Option ''mountpoint''. zfs set mountpoint=/pfad/zum/neuen/mountpunkt pool/dataset Mountet ''pool/dataset'' auf ''/pfad/zum/neuen/mountpunkt'' ==== Quota ==== Für die Datasets können Quotas gesetzt werden, sodass diese eine maximal vorgegebene Größe nicht überschreiten können. zfs set quota=100G home/benutzer1 Legt für das Dataset ''home/benutzer1'' eine Maximalgröße von 100GB fest. ===== Exportieren der Dateisysteme über NFS ===== ZFS Kann die NFS-Exports selbst verwalten. Es muss dann nichts in ''/etc/exports'' eingetragen werden. Es wird allerdings ein Dummy-Export benötigt, weil sonst der NFS-Kernel-Server nicht startet. Dieser kann z.B. so aussehen: # Dummy Export zum starten des NFS-Servers fuer ZFS /mnt/dummy localhost Einen NFS-Export erstellt man dann mit ZFS: zfs set sharenfs="rw=@192.168.2.0/24" pool/dataset Dies exportiert das Dataset ''pool/dataset'' und alle untergeordneten Datasets an alle Rechner im Netz ''192.168.2.0/24''.\\ ''rw'' sorgt dafür, dass die Clients auch schreiben dürfen.\\ Alternativ kann der Export natürlich auch wie gewohnt in die Datei ''/etc/exports'' eingetragen werden. Man sollte sich aber auf eine Variante festlegen, damit man nicht wahnsinnig wird. ===== ZVOLs ===== ZVOLs bilden virtuelle Datenträger auf ZFS ab. Diese können z.B. als virtuelle Festplatte von Virtuellen Maschinen (VMs) verwendet werden. ==== ZVOL erstellen ==== Ein ZVOL mit einer Kapazität von 10GB auf dem Pool "pool" erstellen: zfs create -V 10G pool/zvol_1 Die Abbilder finden sich unter /dev/zvol/"poolname"/"ZVOLname". Also z.B. "/dev/zvol/pool/vm_1". ==== ZVOL für VMs ==== Gängige Dateisysteme verwenden eine Blockgröße von 4 kiB (4096 Bytes). Die standardblockgröße von ZVOLs ist aber 8kiB (8192 Bytes). Um optimale performannce zu erreichen, sollten ZVOLs für VMs mit einer Blockgröße von 4kiB erzeugt werden. Die Blockgröße eines ZVOL kann nachträglich nicht mehr geändert werden. zfs create -b 4K -V 10G pool/vm_1 ==== ZVOL vergrößern ==== Das ZVOL "vm_1" auf "pool" auf 20GB vergrößern: zfs set volsize=20G pool/vm_1 Anschließend kann man mit der VM GParted booten und die Partitionen entsprechend vergrößern. ===== böse Tuning-Optionen ===== Wenn du nicht weißt, was du tust, solltest du diese Optionen **nicht anwenden!** * Synchrones Schreiben generell deaktivieren. Hier für das Dataset "dataset" im Pool "pool". ACHTUNG: Bei einem Stromausfall kann es zu unkontrolliertem Datenverlust kommen! Das Dateisystem wird aber konsistent bleiben. Dies sorgt z.B. für einen erheblich besseren Datendurchsatz beim Schreiben von vielen kleinen Dateien über NFS. Siehe auch [[http://milek.blogspot.de/2010/05/zfs-synchronous-vs-asynchronous-io.html milek.blogspot.de]] zfs set sync=disabled pool/dataset ACHTUNG: wahrscheinlich ist es sinnvoller stattdessen dem Pool ein [[linux:zfs#ZIL (Log) hinzufügen|Log-Device (ZIL) hinzuzufügen!]] ===== Defekte Festplatte ersetzen ===== zpool replace -o ashift=12 pool alte_Festplatte neue_Festplatte Ersetzt ''alte_Festplatte'' durch ''neue_Festplatte''. Festplatten-IDs verwenden, wie beim [[#zpool erstellen| Erstellen eines ZPools]]. ===== Festplatten hinzufügen / entfernen ===== Dies funktioniert nur mit einfachen Spiegeln (mirror) oder einzelnen Festplatten. (und natürlich bei Pools aus mehreren Mirrors.) ==== Festplatte hinzufügen ==== zpool attach -o ashift=12 pool vorhandene_Festplatte neue_Festplatte Fügt der Festplatte ''vorhandene_Festplatte'' den Spiegel ''neue_Festplatte'' hinzu.\\ Man kann auch einem Spiegel eine weitere Festplatte hinzufügen. Dazu genauso vorgehen, und als ''vorhandene_Festplatte'' eine beliebige Festplatte des Spiegels angeben. ==== Festplatte entfernen ==== zpool detach pool Festplatte Entfernt ''Festplatte'' aus dem Pool ''pool''.