ZFS-Grundlagen: Speicher und Leistung

ZFS-Grundlagen: Speicher und Leistung

In diesem Frühjahr haben wir bereits einige Einführungsthemen besprochen, zum Beispiel: So überprüfen Sie die Geschwindigkeit Ihrer Laufwerke и Was ist RAID?. Im zweiten Teil haben wir sogar versprochen, die Leistung verschiedener Multi-Disk-Topologien in ZFS weiter zu untersuchen. Dies ist das Dateisystem der nächsten Generation, das jetzt überall implementiert wird: von Apple auf Ubuntu.

Nun, heute ist der beste Tag, um ZFS kennenzulernen, neugierige Leser. Man muss nur wissen, dass es nach der bescheidenen Meinung des OpenZFS-Entwicklers Matt Ahrens „wirklich schwer“ ist.

Aber bevor wir zu den Zahlen für alle Optionen für eine ZFS-Konfiguration mit acht Festplatten kommen – und das verspreche ich –, müssen wir darüber reden als Im Allgemeinen speichert ZFS Daten auf der Festplatte.

Zpool, vdev und Gerät

ZFS-Grundlagen: Speicher und Leistung
Dieses vollständige Pooldiagramm enthält drei Hilfs-vdevs, eines für jede Klasse und vier für RAIDz2

ZFS-Grundlagen: Speicher und Leistung
Normalerweise gibt es keinen Grund, einen Pool nicht übereinstimmender VDEV-Typen und -Größen zu erstellen – aber nichts hindert Sie daran, dies zu tun, wenn Sie möchten.

Um das ZFS-Dateisystem wirklich zu verstehen, müssen Sie sich seine tatsächliche Struktur genau ansehen. Erstens vereinheitlicht ZFS die herkömmlichen Ebenen der Volume- und Dateisystemverwaltung. Zweitens verwendet es einen transaktionalen Copy-on-Write-Mechanismus. Durch diese Merkmale unterscheidet sich das System strukturell stark von herkömmlichen Dateisystemen und RAID-Arrays. Der erste Satz grundlegender Bausteine, die es zu verstehen gilt, sind der Speicherpool (zpool), das virtuelle Gerät (vdev) und das reale Gerät (device).

zpool

Der Zpool-Speicherpool ist die oberste ZFS-Struktur. Jeder Pool enthält ein oder mehrere virtuelle Geräte. Jeder von ihnen enthält wiederum ein oder mehrere reale Geräte (Gerät). Virtuelle Pools sind in sich geschlossene Blöcke. Ein physischer Computer kann zwei oder mehr separate Pools enthalten, aber jeder ist völlig unabhängig voneinander. Pools können keine virtuellen Geräte gemeinsam nutzen.

Die Redundanz von ZFS liegt auf der Ebene der virtuellen Geräte, nicht auf der Poolebene. Auf Poolebene gibt es absolut keine Redundanz – wenn ein Laufwerks-VDEV oder ein spezielles VDEV verloren geht, geht auch der gesamte Pool verloren.

Moderne Speicherpools können den Verlust eines Caches oder eines Protokolls eines virtuellen Geräts überstehen – allerdings können sie eine kleine Menge fehlerhafter Daten verlieren, wenn sie das vdev-Protokoll während eines Stromausfalls oder eines Systemabsturzes verlieren.

Es gibt ein weit verbreitetes Missverständnis, dass ZFS-„Datenstreifen“ über den gesamten Pool geschrieben werden. Das ist nicht wahr. Zpool ist überhaupt kein lustiges RAID0, es ist eher lustig JBOD mit einem komplexen variablen Verteilungsmechanismus.

Meistens werden die Datensätze entsprechend dem verfügbaren freien Speicherplatz auf die verfügbaren virtuellen Geräte verteilt, sodass sie theoretisch alle gleichzeitig gefüllt werden. In späteren Versionen von ZFS wird die aktuelle vdev-Nutzung (Auslastung) berücksichtigt – wenn ein virtuelles Gerät deutlich ausgelastet ist als ein anderes (z. B. aufgrund der Leselast), wird es trotz der höchsten freien Kapazität vorübergehend zum Schreiben übersprungen Raumverhältnis.

Der in moderne ZFS-Schreibzuweisungsmethoden integrierte Auslastungserkennungsmechanismus kann in Zeiten ungewöhnlich hoher Auslastung die Latenz reduzieren und den Durchsatz erhöhen – dies ist jedoch nicht der Fall Blankovollmacht zum unfreiwilligen Mischen von langsamen Festplatten und schnellen SSDs in einem Pool. Ein solcher ungleicher Pool arbeitet immer noch mit der Geschwindigkeit des langsamsten Geräts, das heißt, als bestünde er vollständig aus solchen Geräten.

vdev

Jeder Speicherpool besteht aus einem oder mehreren virtuellen Geräten (virtuelles Gerät, vdev). Jedes vdev enthält wiederum ein oder mehrere reale Geräte. Die meisten virtuellen Geräte werden für die einfache Datenspeicherung verwendet, es gibt jedoch mehrere vdev-Hilfsklassen, darunter CACHE, LOG und SPECIAL. Jeder dieser vdev-Typen kann eine von fünf Topologien haben: Einzelgerät (Einzelgerät), RAIDz1, RAIDz2, RAIDz3 oder Spiegel (Spiegel).

RAIDz1, RAIDz2 und RAIDz3 sind spezielle Varianten dessen, was die Oldtimer als doppeltes (diagonales) Paritäts-RAID bezeichnen würden. 1, 2 und 3 beziehen sich darauf, wie viele Paritätsblöcke jedem Datenstreifen zugewiesen werden. Anstelle separater Festplatten für die Parität verteilen virtuelle RAIDz-Geräte diese Parität halbgleichmäßig auf die Festplatten. Ein RAIDz-Array kann so viele Festplatten verlieren, wie es über Paritätsblöcke verfügt. Wenn ein weiterer verloren geht, stürzt er ab und nimmt den Speicherpool mit.

Bei gespiegelten virtuellen Geräten (Spiegel-VDEV) wird jeder Block auf jedem Gerät im VDEV gespeichert. Obwohl Spiegel mit zwei Breiten am häufigsten vorkommen, kann sich eine beliebige Anzahl von Geräten in einem Spiegel befinden. In großen Installationen werden häufig Dreifachspiegel verwendet, um die Leseleistung und Fehlertoleranz zu verbessern. Ein Vdev-Spiegel kann jeden Ausfall überstehen, solange mindestens ein Gerät im Vdev weiterhin funktioniert.

Einzelne Vdevs sind von Natur aus gefährlich. Ein solches virtuelles Gerät überlebt keinen einzigen Ausfall – und wenn es als Speicher oder als spezielles VDEV verwendet wird, führt sein Ausfall zur Zerstörung des gesamten Pools. Seien Sie hier sehr, sehr vorsichtig.

CACHE-, LOG- und SPECIAL-VAs können mit jeder der oben genannten Topologien erstellt werden. Bedenken Sie jedoch, dass der Verlust einer SPECIAL-VA den Verlust des Pools bedeutet. Daher wird eine redundante Topologie dringend empfohlen.

Gerät

Dies ist wahrscheinlich der am einfachsten zu verstehende Begriff in ZFS – es handelt sich im wahrsten Sinne des Wortes um ein Block-Random-Access-Gerät. Denken Sie daran, dass virtuelle Geräte aus einzelnen Geräten bestehen, während ein Pool aus virtuellen Geräten besteht.

Festplatten – entweder magnetische oder Festkörperplatten – sind die am häufigsten verwendeten Blockgeräte, die als Bausteine ​​von vdev verwendet werden. Allerdings reicht jedes Gerät mit einem Deskriptor in /dev aus, sodass ganze Hardware-RAID-Arrays als separate Geräte verwendet werden können.

Eine einfache Rohdatei ist eines der wichtigsten alternativen Blockgeräte, aus denen ein VDEV erstellt werden kann. Testpools von spärliche Dateien ist eine sehr praktische Möglichkeit, Poolbefehle zu überprüfen und zu sehen, wie viel Speicherplatz in einem Pool oder virtuellen Gerät einer bestimmten Topologie verfügbar ist.

ZFS-Grundlagen: Speicher und Leistung
Sie können in wenigen Sekunden einen Testpool aus Sparse-Dateien erstellen – vergessen Sie jedoch nicht, anschließend den gesamten Pool und seine Komponenten zu löschen

Nehmen wir an, Sie möchten einen Server auf acht Festplatten aufstellen und planen, 10-TB-Festplatten (~9300 GiB) zu verwenden – sind sich aber nicht sicher, welche Topologie Ihren Anforderungen am besten entspricht. Im obigen Beispiel erstellen wir in Sekundenschnelle einen Testpool aus Dateien mit geringer Dichte – und jetzt wissen wir, dass ein RAIDz2-vdev mit acht 10-TB-Festplatten 50 TiB nutzbare Kapazität bietet.

Eine weitere spezielle Geräteklasse ist SPARE (Ersatz). Hot-Swap-Geräte gehören im Gegensatz zu normalen Geräten zum gesamten Pool und nicht zu einem einzelnen virtuellen Gerät. Wenn ein Vdev im Pool ausfällt und ein Ersatzgerät mit dem Pool verbunden und verfügbar ist, wird es automatisch dem betroffenen Vdev beitreten.

Nach der Verbindung mit dem betroffenen vdev beginnt das Ersatzgerät, Kopien oder Rekonstruktionen der Daten zu empfangen, die sich auf dem fehlenden Gerät befinden sollten. Bei herkömmlichem RAID wird dies als Neuaufbau bezeichnet, während es bei ZFS als Resilvering bezeichnet wird.

Es ist wichtig zu beachten, dass Ersatzgeräte ausgefallene Geräte nicht dauerhaft ersetzen. Dies ist nur ein vorübergehender Ersatz, um die Zeitspanne zu verkürzen, in der vdev beeinträchtigt wird. Nachdem der Administrator das ausgefallene Vdev ersetzt hat, wird die Redundanz auf diesem permanenten Gerät wiederhergestellt, und SPARE wird vom Vdev getrennt und arbeitet wieder als Ersatzgerät für den gesamten Pool.

Datensätze, Blöcke und Sektoren

Bei den nächsten Bausteinen, die wir auf unserer ZFS-Reise verstehen sollten, geht es weniger um die Hardware als vielmehr darum, wie die Daten selbst organisiert und gespeichert werden. Wir überspringen hier ein paar Ebenen – wie zum Beispiel Metaslab – um die Details nicht zu überladen und gleichzeitig ein Verständnis für die Gesamtstruktur zu bewahren.

Datensatz (Datensatz)

ZFS-Grundlagen: Speicher und Leistung
Wenn wir zum ersten Mal einen Datensatz erstellen, wird der gesamte verfügbare Poolraum angezeigt. Dann legen wir die Quote fest – und ändern den Mount-Punkt. Magie!

ZFS-Grundlagen: Speicher und Leistung
Zvol ist größtenteils nur ein Datensatz ohne Dateisystemschicht, den wir hier durch ein völlig normales ext4-Dateisystem ersetzen.

Ein ZFS-Datensatz entspricht in etwa einem standardmäßig gemounteten Dateisystem. Wie ein normales Dateisystem sieht es auf den ersten Blick wie „nur ein weiterer Ordner“ aus. Aber genau wie normale einhängbare Dateisysteme verfügt jeder ZFS-Datensatz über seinen eigenen Satz grundlegender Eigenschaften.

Zunächst kann einem Datensatz eine Quote zugewiesen werden. Wenn festgelegt zfs set quota=100G poolname/datasetname, dann können Sie nicht in den bereitgestellten Ordner schreiben /poolname/datasetname mehr als 100 GiB.

Ist Ihnen das Vorhandensein – und Fehlen – von Schrägstrichen am Anfang jeder Zeile aufgefallen? Jeder Datensatz hat seinen eigenen Platz sowohl in der ZFS-Hierarchie als auch in der System-Mount-Hierarchie. In der ZFS-Hierarchie gibt es keinen führenden Schrägstrich – Sie beginnen mit dem Poolnamen und dann dem Pfad von einem Datensatz zum nächsten. Zum Beispiel, pool/parent/child für einen Datensatz mit dem Namen child unter dem übergeordneten Datensatz parent in einem Pool mit einem kreativen Namen pool.

Standardmäßig entspricht der Mountpunkt des Datensatzes seinem Namen in der ZFS-Hierarchie, mit einem führenden Schrägstrich – dem benannten Pool pool montiert als /pool, Datensatz parent montiert /pool/parentund der untergeordnete Datensatz child montiert /pool/parent/child. Der System-Mount-Punkt des Datensatzes kann jedoch geändert werden.

Wenn wir angeben zfs set mountpoint=/lol pool/parent/child, dann der Datensatz pool/parent/child auf dem System montiert als /lol.

Zusätzlich zu Datensätzen sollten wir Volumes (zvols) erwähnen. Ein Volume ist ungefähr dasselbe wie ein Datensatz, außer dass es eigentlich kein Dateisystem hat – es ist nur ein Blockgerät. Sie können zum Beispiel erstellen zvol Mit Namen mypool/myzvol, formatieren Sie es dann mit einem ext4-Dateisystem und mounten Sie dann dieses Dateisystem – Sie haben jetzt ein ext4-Dateisystem, aber mit allen Sicherheitsfunktionen von ZFS! Das mag auf einer einzelnen Maschine albern erscheinen, ist aber als Backend beim Exportieren eines iSCSI-Geräts viel sinnvoller.

Blöcke

ZFS-Grundlagen: Speicher und Leistung
Die Datei wird durch einen oder mehrere Blöcke dargestellt. Jeder Block wird auf einem virtuellen Gerät gespeichert. Die Blockgröße entspricht normalerweise dem Parameter Datensatzgröße, kann aber reduziert werden auf 2^Schichtwenn es Metadaten oder eine kleine Datei enthält.

ZFS-Grundlagen: Speicher und Leistung
Wir wirklich wirklich Ich mache keine Witze über die enormen Leistungseinbußen, wenn Sie eine zu kleine Verschiebung einstellen

In einem ZFS-Pool werden alle Daten, einschließlich Metadaten, in Blöcken gespeichert. Die maximale Blockgröße für jeden Datensatz wird in der Eigenschaft definiert recordsize (Datensatzgröße). Die Datensatzgröße kann geändert werden, aber die Größe oder Position von Blöcken, die bereits in den Datensatz geschrieben wurden, ändert sich dadurch nicht – es wirkt sich nur auf neue Blöcke aus, wenn sie geschrieben werden.

Sofern nicht anders angegeben, beträgt die aktuelle Standarddatensatzgröße 128 KiB. Es ist ein schwieriger Kompromiss, wenn die Leistung nicht perfekt ist, aber in den meisten Fällen ist es auch nicht so schlimm. Recordsize kann auf einen beliebigen Wert von 4K bis 1M eingestellt werden (mit erweiterten Einstellungen). recordsize Sie können noch mehr installieren, aber das ist selten eine gute Idee.

Jeder Block bezieht sich auf die Daten nur einer Datei – Sie können nicht zwei verschiedene Dateien in einen Block packen. Jede Datei besteht je nach Größe aus einem oder mehreren Blöcken. Wenn die Dateigröße kleiner als die Datensatzgröße ist, wird sie in einer kleineren Blockgröße gespeichert. Beispielsweise belegt ein Block mit einer 2-KiB-Datei nur einen 4-KiB-Sektor auf der Festplatte.

Wenn die Datei groß genug ist und mehrere Blöcke benötigt, werden alle Datensätze in dieser Datei die gleiche Größe haben recordsize - einschließlich des letzten Eintrags, dessen Hauptteil sein kann ungenutzter Raum.

Zvols haben keine Eigenschaft recordsize – stattdessen haben sie eine gleichwertige Eigenschaft volblocksize.

Sektoren

Der letzte, grundlegendste Baustein ist der Sektor. Es ist die kleinste physische Einheit, die auf das zugrunde liegende Gerät geschrieben oder von diesem gelesen werden kann. Mehrere Jahrzehnte lang verwendeten die meisten Festplatten 512-Byte-Sektoren. Neuerdings sind die meisten Festplatten auf 4-KiB-Sektoren eingestellt, und einige – insbesondere SSDs – haben 8-KiB-Sektoren oder sogar mehr.

Das ZFS-System verfügt über eine Eigenschaft, mit der Sie die Sektorgröße manuell festlegen können. Diese Liegenschaft ashift. Etwas verwirrend ist, dass ashift eine Zweierpotenz ist. Zum Beispiel, ashift=9 bedeutet eine Sektorgröße von 2^9 oder 512 Bytes.

ZFS fragt das Betriebssystem nach detaillierten Informationen zu jedem Blockgerät, wenn es einem neuen vdev hinzugefügt wird, und installiert ashift theoretisch automatisch ordnungsgemäß auf der Grundlage dieser Informationen. Leider lügen viele Laufwerke über ihre Sektorgröße, um die Kompatibilität mit Windows XP aufrechtzuerhalten (das Laufwerke mit anderen Sektorgrößen nicht verstehen konnte).

Dies bedeutet, dass einem ZFS-Administrator dringend empfohlen wird, die tatsächliche Sektorgröße seiner Geräte zu kennen und manuell festzulegen ashift. Wenn ashift zu niedrig eingestellt ist, steigt die Anzahl der Lese-/Schreibvorgänge astronomisch an. Das Schreiben von 512-Byte-„Sektoren“ in einen echten 4-KiB-Sektor bedeutet also, dass man den ersten „Sektor“ schreiben, dann den 4-KiB-Sektor lesen, ihn mit einem zweiten 512-Byte-„Sektor“ modifizieren und ihn in den neuen zurückschreiben muss 4-KiB-Sektor usw. für jeden Eintrag.

In der realen Welt trifft eine solche Strafe Samsung EVO SSDs, für die ashift=13, aber diese SSDs lügen hinsichtlich ihrer Sektorgröße und daher ist die Standardeinstellung auf eingestellt ashift=9. Wenn ein erfahrener Systemadministrator diese Einstellung nicht ändert, funktioniert diese SSD langsamer herkömmliche magnetische Festplatte.

Zum Vergleich, für zu große Größe ashift es gibt praktisch keine Strafe. Es gibt keine wirklichen Leistungseinbußen und die Zunahme des ungenutzten Speicherplatzes ist verschwindend gering (bzw. Null bei aktivierter Komprimierung). Daher empfehlen wir dringend, auch Laufwerke zu installieren, die 512-Byte-Sektoren verwenden ashift=12 oder ashift=13mit Zuversicht in die Zukunft blicken.

Immobilien ashift wird für jedes virtuelle vdev-Gerät festgelegt und nicht für den Pool, wie viele fälschlicherweise denken – und ändert sich nach der Installation nicht. Wenn Sie versehentlich getroffen haben ashift Wenn Sie einem Pool ein neues vdev hinzufügen, haben Sie diesen Pool unwiederbringlich mit einem Gerät mit geringer Leistung verunreinigt, und es bleibt normalerweise keine andere Wahl, als den Pool zu zerstören und von vorne zu beginnen. Selbst das Entfernen von vdev wird Sie nicht vor einer fehlerhaften Konfiguration bewahren ashift!

Copy-on-Write-Mechanismus

ZFS-Grundlagen: Speicher und Leistung
Wenn ein normales Dateisystem Daten überschreiben muss, ändert es jeden Block dort, wo er sich befindet

ZFS-Grundlagen: Speicher und Leistung
Ein Copy-on-Write-Dateisystem schreibt eine neue Blockversion und entsperrt dann die alte Version

ZFS-Grundlagen: Speicher und Leistung
Wenn wir abstrakt die tatsächliche physische Position der Blöcke ignorieren, wird unser „Datenkomet“ zu einem „Datenwurm“ vereinfacht, der sich von links nach rechts über die Karte des verfügbaren Raums bewegt

ZFS-Grundlagen: Speicher und Leistung
Jetzt können wir uns ein gutes Bild davon machen, wie Copy-on-Write-Snapshots funktionieren – jeder Block kann zu mehreren Snapshots gehören und bleibt bestehen, bis alle zugehörigen Snapshots zerstört sind

Der Copy-on-Write-Mechanismus (CoW) ist die grundlegende Grundlage dafür, was ZFS zu einem so erstaunlichen System macht. Das Grundkonzept ist einfach: Wenn Sie ein herkömmliches Dateisystem auffordern, eine Datei zu ändern, wird es genau das tun, was Sie angefordert haben. Wenn Sie ein Copy-on-Write-Dateisystem bitten, dasselbe zu tun, wird es „ok“ sagen, Sie aber belügen.

Stattdessen schreibt ein Copy-on-Write-Dateisystem eine neue Version des geänderten Blocks und aktualisiert dann die Metadaten der Datei, um die Verknüpfung des alten Blocks aufzuheben und den neuen Block, den Sie gerade geschrieben haben, damit zu verknüpfen.

Das Lösen des alten Blocks und das Verknüpfen des neuen Blocks erfolgt in einem Vorgang und kann daher nicht unterbrochen werden. Wenn Sie danach den Block ausschalten, haben Sie eine neue Version der Datei, und wenn Sie ihn früher ausschalten, haben Sie die alte Version . In jedem Fall kommt es zu keinen Konflikten im Dateisystem.

Copy-on-Write erfolgt in ZFS nicht nur auf Dateisystemebene, sondern auch auf der Datenträgerverwaltungsebene. Dies bedeutet, dass ZFS nicht durch Leerzeichen beeinträchtigt wird (ein Loch im RAID) – ein Phänomen, bei dem der Strip nur teilweise aufzeichnen konnte, bevor das System abstürzte und das Array nach einem Neustart beschädigt wurde. Hier wird der Stripe atomar geschrieben, vdev ist immer sequentiell und Bob ist dein Onkel.

ZIL: ZFS-Absichtsprotokoll

ZFS-Grundlagen: Speicher und Leistung
Das ZFS-System behandelt synchrone Schreibvorgänge auf besondere Weise: Es speichert sie vorübergehend, aber sofort in ZIL, bevor es sie später zusammen mit asynchronen Schreibvorgängen dauerhaft schreibt.

ZFS-Grundlagen: Speicher und Leistung
Normalerweise werden in eine ZIL geschriebene Daten nie wieder gelesen. Aber es ist nach einem Systemabsturz möglich

ZFS-Grundlagen: Speicher und Leistung
SLOG oder sekundäres LOG-Gerät ist nur ein spezielles – und vorzugsweise sehr schnelles – vdev, bei dem die ZIL getrennt vom Hauptspeicher gespeichert werden kann

ZFS-Grundlagen: Speicher und Leistung
Nach einem Absturz werden alle fehlerhaften Daten in ZIL wiedergegeben. In diesem Fall befindet sich ZIL auf SLOG und wird daher von dort aus wiedergegeben

Es gibt zwei Hauptkategorien von Schreibvorgängen: synchrone (sync) und asynchrone (async). Bei den meisten Workloads erfolgt die überwiegende Mehrheit der Schreibvorgänge asynchron – das Dateisystem ermöglicht die Aggregation und Ausgabe in Stapeln, wodurch die Fragmentierung verringert und der Durchsatz erheblich erhöht wird.

Eine ganz andere Sache sind synchronisierte Aufnahmen. Wenn eine Anwendung einen synchronen Schreibvorgang anfordert, teilt sie dem Dateisystem mit: „Sie müssen dies in den nichtflüchtigen Speicher übertragen.“ jetzt sofortBis dahin kann ich nichts anderes tun. Daher sollten synchrone Schreibvorgänge sofort auf die Festplatte übertragen werden – und wenn dies die Fragmentierung erhöht oder den Durchsatz verringert, dann ist das so.

ZFS handhabt synchrone Schreibvorgänge anders als normale Dateisysteme – anstatt sie sofort in den regulären Speicher zu übertragen, schreibt ZFS sie in einen speziellen Speicherbereich namens ZFS Intent Log (ZIL). Der Trick besteht darin, dass diese Aufzeichnungen auch verbleiben im Speicher und werden zusammen mit normalen asynchronen Schreibanforderungen aggregiert, um später als ganz normale TXGs (Transaktionsgruppen) in den Speicher geleert zu werden.

Im Normalbetrieb wird auf die ZIL geschrieben und nie wieder gelesen. Wenn nach wenigen Augenblicken die Datensätze aus der ZIL in gewöhnlichen TXGs aus dem RAM in den Hauptspeicher übernommen werden, werden sie von der ZIL getrennt. Das einzige Mal, dass etwas aus der ZIL gelesen wird, ist, wenn der Pool importiert wird.

Wenn ZFS ausfällt – ein Betriebssystemabsturz oder ein Stromausfall –, während Daten in der ZIL vorhanden sind, werden diese Daten beim nächsten Poolimport gelesen (z. B. beim Neustart des Notfallsystems). Alles in der ZIL wird gelesen, in TXGs gruppiert, in den Hauptspeicher übertragen und dann während des Importvorgangs von der ZIL getrennt.

Eine der vdev-Hilfsklassen heißt LOG oder SLOG, das sekundäre Gerät von LOG. Es hat einen Zweck: dem Pool ein separates und vorzugsweise viel schnelleres, sehr schreibresistentes vdev zur Verfügung zu stellen, um die ZIL zu speichern, anstatt die ZIL im Haupt-vdev-Speicher zu speichern. Das ZIL selbst verhält sich gleich, egal wo es gespeichert ist, aber wenn das LOG-vdev eine sehr hohe Schreibleistung hat, sind synchrone Schreibvorgänge schneller.

Das Hinzufügen eines vdev mit LOG zum Pool funktioniert nicht kann nicht Verbessern Sie die asynchrone Schreibleistung – auch wenn Sie alle Schreibvorgänge in ZIL erzwingen zfs set sync=always, werden sie weiterhin auf die gleiche Weise und im gleichen Tempo wie ohne Protokoll mit dem Hauptspeicher in TXG verknüpft. Die einzige direkte Leistungsverbesserung ist die Latenz synchroner Schreibvorgänge (da eine schnellere Protokollierung die Vorgänge beschleunigt). sync).

In einer Umgebung, die bereits viele synchrone Schreibvorgänge erfordert, kann vdev LOG jedoch indirekt asynchrone Schreibvorgänge und nicht zwischengespeicherte Lesevorgänge beschleunigen. Das Auslagern von ZIL-Einträgen in ein separates vdev-LOG bedeutet weniger Konflikte um IOPS auf dem Primärspeicher, was die Leistung aller Lese- und Schreibvorgänge in gewissem Maße verbessert.

Schnappschüsse

Der Copy-on-Write-Mechanismus ist auch eine notwendige Grundlage für atomare ZFS-Snapshots und inkrementelle asynchrone Replikation. Das aktive Dateisystem verfügt über einen Zeigerbaum, der alle Datensätze mit aktuellen Daten markiert. Wenn Sie einen Schnappschuss erstellen, erstellen Sie einfach eine Kopie dieses Zeigerbaums.

Wenn ein Datensatz im aktiven Dateisystem überschrieben wird, schreibt ZFS zunächst die neue Blockversion in ungenutzten Speicherplatz. Anschließend wird die alte Version des Blocks vom aktuellen Dateisystem getrennt. Wenn sich jedoch ein Snapshot auf den alten Block bezieht, bleibt dieser unverändert. Der alte Block wird erst dann als freier Speicherplatz wiederhergestellt, wenn alle Snapshots, die auf diesen Block verweisen, zerstört sind!

Replikation

ZFS-Grundlagen: Speicher und Leistung
Meine Steam-Bibliothek im Jahr 2015 war 158 GiB groß und enthielt 126 Dateien. Dies kommt der optimalen Situation für rsync ziemlich nahe – die ZFS-Replikation über das Netzwerk war „nur“ 927 % schneller.

ZFS-Grundlagen: Speicher und Leistung
Im selben Netzwerk ist die Replikation einer einzelnen 40-GB-Imagedatei einer virtuellen Windows 7-Maschine eine völlig andere Geschichte. Die ZFS-Replikation ist 289-mal schneller als rsync – oder „nur“ 161-mal schneller, wenn Sie klug genug sind, rsync mit --inplace aufzurufen.

ZFS-Grundlagen: Speicher und Leistung
Wenn ein VM-Image skaliert wird, skalieren Rsync-Probleme mit. 1,9 TiB ist für ein modernes VM-Image nicht so groß – aber groß genug, dass die ZFS-Replikation 1148-mal schneller als rsync ist, selbst mit dem Argument --inplace von rsync

Sobald Sie verstanden haben, wie Snapshots funktionieren, sollte es Ihnen leicht fallen, die Essenz der Replikation zu verstehen. Da ein Snapshot nur ein Baum von Zeigern auf Datensätze ist, folgt daraus, dass wir dies tun zfs send Snapshot, dann senden wir sowohl diesen Baum als auch alle damit verbundenen Datensätze. Wenn wir das verschicken zfs send в zfs receive Auf dem Ziel schreibt es sowohl den tatsächlichen Inhalt des Blocks als auch den Zeigerbaum, der auf die Blöcke verweist, in den Zieldatensatz.

Im zweiten Teil wird es noch interessanter zfs send. Wir haben jetzt zwei Systeme, jedes enthält poolname/datasetname@1, und Sie machen einen neuen Schnappschuss poolname/datasetname@2. Daher haben Sie im ursprünglichen Pool datasetname@1 и datasetname@2, und im Zielpool bisher nur der erste Snapshot datasetname@1.

Da wir einen gemeinsamen Schnappschuss zwischen der Quelle und dem Ziel haben datasetname@1, Wir können es schaffen inkrementell zfs send darüber. Wenn wir zum System sagen zfs send -i poolname/datasetname@1 poolname/datasetname@2Es vergleicht zwei Zeigerbäume. Alle Zeiger, die nur in existieren @2, beziehen sich offensichtlich auf neue Blöcke – wir benötigen also den Inhalt dieser Blöcke.

Auf einem Remote-System wird ein inkrementeller Vorgang verarbeitet send genauso einfach. Zuerst schreiben wir alle neuen Einträge, die im Stream enthalten sind send, und fügen Sie dann Zeiger auf diese Blöcke hinzu. Voila, das haben wir @2 im neuen System!

Die asynchrone inkrementelle Replikation von ZFS ist eine enorme Verbesserung gegenüber früheren, nicht auf Snapshots basierenden Methoden wie rsync. In beiden Fällen werden nur geänderte Daten übertragen – rsync muss aber vorher erfolgen lies die Von der Festplatte alle Daten auf beiden Seiten, um die Summe zu überprüfen und zu vergleichen. Im Gegensatz dazu liest die ZFS-Replikation nur Zeigerbäume – und alle Blöcke, die nicht im freigegebenen Snapshot vorhanden sind.

Integrierte Komprimierung

Der Copy-on-Write-Mechanismus vereinfacht auch das Inline-Komprimierungssystem. In einem herkömmlichen Dateisystem ist die Komprimierung problematisch – sowohl die alte als auch die neue Version der geänderten Daten befinden sich im selben Bereich.

Wenn wir ein Datenelement in der Mitte einer Datei betrachten, das zu Beginn ein Megabyte mit Nullen ab 0x00000000 usw. enthält, ist es sehr einfach, es auf einen Sektor auf der Festplatte zu komprimieren. Aber was passiert, wenn wir dieses Megabyte an Nullen durch ein Megabyte inkompressibler Daten wie JPEG oder Pseudozufallsrauschen ersetzen? Unerwarteterweise erfordert dieses Megabyte an Daten nicht einen, sondern 256 4-KiB-Sektoren, und an dieser Stelle auf der Festplatte ist nur ein Sektor reserviert.

Bei ZFS gibt es dieses Problem nicht, da geänderte Datensätze immer in ungenutzten Speicherplatz geschrieben werden – der ursprüngliche Block belegt nur einen 4-KiB-Sektor und der neue Datensatz belegt 256, aber das ist kein Problem – ein kürzlich geändertes Fragment aus dem „ Mitte“ der Datei würde in ungenutzten Speicherplatz geschrieben werden, unabhängig davon, ob sich ihre Größe geändert hat oder nicht, also ist dies bei ZFS eine ganz normale Situation.

Die native ZFS-Komprimierung ist standardmäßig deaktiviert und das System bietet austauschbare Algorithmen – derzeit LZ4, gzip (1-9), LZJB und ZLE.

  • LZ4 ist ein Streaming-Algorithmus, der für die meisten Anwendungsfälle extrem schnelle Komprimierung und Dekomprimierung sowie Leistungsvorteile bietet – selbst auf relativ langsamen CPUs.
  • GZIP ist ein ehrwürdiger Algorithmus, den alle Unix-Benutzer kennen und lieben. Er kann mit den Komprimierungsstufen 1–9 implementiert werden, wobei das Komprimierungsverhältnis und die CPU-Auslastung steigen, wenn man sich der Stufe 9 nähert. Der Algorithmus eignet sich gut für alle Text- (oder andere stark komprimierbare) Anwendungsfälle, verursacht aber ansonsten oft CPU-Probleme – verwenden Sie ihn mit Vorsicht, insbesondere auf höheren Ebenen.
  • LZJB ist der ursprüngliche Algorithmus in ZFS. Es ist veraltet und sollte nicht mehr verwendet werden, das LZ4 übertrifft es in jeder Hinsicht.
  • FALSCH - Zero-Level-Codierung, Zero-Level-Codierung. Es berührt normale Daten überhaupt nicht, sondern komprimiert große Folgen von Nullen. Nützlich für vollständig inkomprimierbare Datensätze (z. B. JPEG, MP4 oder andere bereits komprimierte Formate), da inkompressible Daten ignoriert werden, aber ungenutzter Speicherplatz in den resultierenden Datensätzen komprimiert wird.

Wir empfehlen die LZ4-Komprimierung für fast alle Anwendungsfälle; Die Leistungseinbußen bei inkompressiblen Daten sind sehr gering Wachstum Die Leistung für typische Daten ist erheblich. Kopieren eines virtuellen Maschinenimages für eine Neuinstallation des Windows-Betriebssystems (frisch installiertes Betriebssystem, noch keine Daten darin) mit compression=lz4 27 % schneller bestanden als mit compression=noneIn diesen Test im Jahr 2015.

ARC – adaptiver Ersatzcache

ZFS ist das einzige uns bekannte moderne Dateisystem, das seinen eigenen Lese-Caching-Mechanismus verwendet, anstatt sich auf den Seitencache des Betriebssystems zu verlassen, um Kopien kürzlich gelesener Blöcke im RAM zu speichern.

Auch wenn der native Cache nicht ohne Probleme ist – ZFS kann nicht so schnell auf neue Speicherzuweisungsanfragen reagieren wie der Kernel, also die neue Herausforderung malloc() bei der Speicherzuweisung kann fehlschlagen, wenn der aktuell von ARC belegte RAM benötigt wird. Aber es gibt gute Gründe, zumindest vorerst einen eigenen Cache zu verwenden.

Alle bekannten modernen Betriebssysteme, einschließlich MacOS, Windows, Linux und BSD, verwenden den LRU-Algorithmus (Least Recent Used), um den Seitencache zu implementieren. Dies ist ein primitiver Algorithmus, der den zwischengespeicherten Block nach jedem Lesevorgang „in der Warteschlange nach oben“ verschiebt und die Blöcke nach Bedarf „in der Warteschlange nach unten“ verschiebt, um neue Cache-Fehler hinzuzufügen (Blöcke, die von der Festplatte und nicht aus dem Cache gelesen werden sollten). hoch.

Der Algorithmus funktioniert normalerweise gut, aber auf Systemen mit großen Arbeitsdatensätzen führt LRU leicht zu Thrashing – dem Entfernen häufig benötigter Blöcke, um Platz für Blöcke zu schaffen, die nie wieder aus dem Cache gelesen werden.

ARC ist ein viel weniger naiver Algorithmus, den man sich als „gewichteten“ Cache vorstellen kann. Jedes Mal, wenn ein zwischengespeicherter Block gelesen wird, wird er etwas „schwerer“ und schwieriger zu entfernen – und das sogar nach dem Entfernen eines Blocks verfolgt innerhalb einer bestimmten Zeitspanne. Ein Block, der entfernt wurde, dann aber wieder in den Cache eingelesen werden muss, wird ebenfalls „schwerer“.

Das Endergebnis all dessen ist ein Cache mit einer viel höheren Trefferquote, dem Verhältnis zwischen Cache-Hits (aus dem Cache durchgeführten Lesevorgängen) und Cache-Misses (Lesevorgängen von der Festplatte). Dies ist eine äußerst wichtige Statistik – nicht nur, dass die Cache-Treffer selbst um Größenordnungen schneller bedient werden, auch Cache-Fehltreffer können schneller bedient werden, denn je mehr Cache-Treffer es gibt, desto weniger gleichzeitige Festplattenanfragen und desto geringer ist die Latenz für die verbleibenden Misses Das muss mit der Festplatte bedient werden.

Abschluss

Nachdem wir die grundlegende Semantik von ZFS kennengelernt haben – wie Copy-on-Write funktioniert, sowie die Beziehungen zwischen Speicherpools, virtuellen Geräten, Blöcken, Sektoren und Dateien – sind wir bereit, die reale Leistung mit realen Zahlen zu diskutieren.

Im nächsten Teil werfen wir einen Blick auf die tatsächliche Leistung von Pools mit gespiegelten vdevs und RAIDz im Vergleich zueinander und auch im Vergleich zu den traditionellen Linux-Kernel-RAID-Topologien, die wir untersucht haben. früher.

Zuerst wollten wir nur die Grundlagen – die ZFS-Topologien selbst – behandeln, aber danach wie Bereiten wir uns darauf vor, über die erweiterte Einrichtung und Optimierung von ZFS zu sprechen, einschließlich der Verwendung zusätzlicher VDEV-Typen wie L2ARC, SLOG und Special Allocation.

Source: habr.com

Kommentar hinzufügen