Warum sendet / empfängt ZFS so viele Daten in meinem LAN?

518
Stilez

Erst letztes Wochenende habe ich einen neuen (sauberen) Sicherungsserver für meinen FreeNAS-Hauptcomputer eingerichtet und eine manuelle vollständige Poolsicherung zwischen ihnen gestartet. Beide Maschinen sind Unternehmenshardware und laufen schnell, die Verbindung besteht aus einem direkten 10G-Optik-LAN (Chelsio). Beide Maschinen verfügen über eine Menge schneller NVMe ZIL / Cache und 128 GB schnelles ddr4 mit Xeon v4- und Supermicro-Baseboards. Bei dem Pool, den ich repliziere / kopiere, handelt es sich um tatsächliche 14 GB-Daten, die mit 35 GB referenzierten Daten (2,5-fach dedup) belegt sind. Bei den Pools handelt es sich um gestreifte Spiegel (4 Sätze von 3-Wege-Spiegeln mit Enterprise 6 + TB 7200-Platten) und nicht um RaidZ. Daher haben sie keine Parität, um sie zu verlangsamen. Auf den Servern oder ihren Verbindungen läuft außer den SSH-Verbindungen für die Übertragungen nichts anderes. Der zfs sendBefehl enthält die Argumente, die zum Senden der abgeleiteten Daten erforderlich sind (obgleich durch Übersehen, nicht komprimiert).

Befehl am Absender:

zfs send -vvDRLe mypool@latest_snapshot | nc -N BACKUP_IP BACKUP_PORT 

Befehl an den Empfänger:

nc -l PORT | zfs receive -vvFsd my_pool 

Ich habe mit einem von zwei Dingen gerechnet: Entweder es sendet 14 TB und endet, oder es sendet 35 TB, aber die 21 TB, die bereits gesendet werden (deduierte Daten), gehen sehr schnell und nur 14 und ein bisschen TB müssen gesendet werden. Stattdessen scheint es jedoch beabsichtigt zu sein, alle 35 TB vollständig zu senden, und dabei unglaublich langsam - habe ich etwas falsch gemacht oder Missverständnisse gemacht?

Was ich nicht verstehe, ist, dass selbst beim Serialisieren der Snapshots / Datasets die Backup-Server-Datenträger zu fast 100% laufen gstatund dies bereits seit vier vollen Tagen tun. Die Daten kommen korrekt an (ich kann die abgeschlossenen Snaps / Datasets einhängen). Das Senden des gesamten Pools sieht jedoch so aus, als würde er etwa 7 Tage in Anspruch nehmen, mit fast 100% Festplattenaktivität.

Das Übertragen von 14 TB oder sogar 35 TB auf einer 10G-Verbindung zwischen zwei schnellen Servern - egal welche Statusinformationen auf der Konsole angezeigt werden - sollte nicht so lange dauern, es sei denn, es ist unglaublich ineffizient, was unwahrscheinlich erscheint.

Beide Systeme können sogar die HDD-Spinner mit fast 500 MB / s lesen und schreiben, und ZFS optimiert den Festplattenzugriff und muss die Daten nicht neu einrichten, da diese bereits gesendet werden.

Warum dauert das so lange? Warum werden nicht nur die rohen Blöcke im Pool nur einmal gesendet?

Antworten auf einige Punkte aus Kommentaren:

  1. netcat (nc): netcat (nc) Bietet einen transparenten, unverschlüsselten TCP / TCP-Transport / Tunnel, um Daten zwischen zwei Systemen zu pfeifen (unter anderem) - ein bisschen wie ssh / VPN, aber keine Verlangsamung oder Umpackung außer dem bloßen TCP-Handshake auf der Leitung. Soweit zfs send/ zfs receivebetroffen sind sie sind in der direkten Kommunikation, und darüber hinaus eine kleine Latenz der netcatsollte Link mit der maximalen Geschwindigkeit ausführen, die hand senden / empfangen kann.
  2. Geschwindigkeit der Spiegelplatte spiegeln : Ein Spiegel schreibt mit der niedrigsten Geschwindigkeit seiner Festplatten, aber ZFS behandelt die Festplatten als gestreifte Spiegelung (Datenstreifen über 4 vdevs auf beiden Systemen, und jede vdev ist eine Spiegelung). Wenn der Quellpool zu 55% voll und der dest-Pool leer ist und angenommen wird, dass die CPUs mithalten können, sollte zfs in der Lage sein, gleichzeitig von 12 Festplatten zu lesen und auf 4 Festplatten zu schreiben, und die Schreibvorgänge sollten alle sequentiell sein andere IO-Aktivität. Ich denke, die langsamste Festplatte in einem Spiegel kann seq bei> = 125 MB / s schreiben, was weit unter der Rate für eine moderne Enterprise 7200 HDD liegt, und das Backup kann sequentiell statt zufälliger E / A gefüllt werden. Hier bekomme ich eine dauerhafte Replikationsrate von >> 500 MB / s.
  3. Dedup-Tabelle / RAM-Angemessenheit: Die Dedup-Tabelle hat etwa 40 GB RAM (von Bytes pro Eintrag x Gesamtblöcke im Quellpool pro zdb). Ich habe ein sysctl auf beiden Systemen eingerichtet, um 85 GB RAM für die Dedup-Tabelle und andere Metadaten, also etwa 35 GB für zwischengespeicherte Daten, zu reservieren, bevor L2ARC verwendet wird (wenn es mit send / rcv verwendet wird). Daher sollten dedup und Metadaten auf beiden Computern nicht aus dem RAM entfernt werden.

Geschwindigkeits- und Fortschrittsupdate:

  • Nach 5 Tagen Laufzeit habe ich einige Fortschrittsstatistiken. Es werden Daten mit durchschnittlich 58 MB / s gesendet. Nicht ganz katastrophal, aber dennoch untermauert sie die obige Frage. Ich würde eine Rate von ca. 10 x erwarten, da die Festplatten-Sets bis zu 12 Festplatten gleichzeitig lesen können (fast 2 GB / s) und bis zu 4 Festplatten gleichzeitig schreiben können (etwa 500 GB / s). Die Daten müssen nicht (AFAIK) oder neu erstellt werden, sie laufen auf 3,5-GHz-4 + 8-Core-Xeon-V4s mit Tonnen RAM auf beiden Systemen und einem LAN, das 1 GB / Sek.
2
Wenn "zfs send" 35 TB sendet, wie können Sie dann von "nc" erfahren, welche Daten bereits gesendet wurden? grawity vor 5 Jahren 0
Netcat ist hier sicherlich nur ein transparenter Transport zwischen den Prozessen "zfs send" und "zfs receive". Es muss nichts wissen, mehr als ein SSH- oder VPN-Prozess, um Rsync oder andere Protokolle zu verstehen, die durch sie getunnelt werden? Es ist nicht üblich, dass ein unverschlüsselter Port-to-Port-Transporttunnel beeinflusst, ob "zfs send" 14 oder 35 TB an Quelldaten (nicht transportiert) in seiner Statusausgabe taktet oder eine Woche statt einen Tag in Anspruch nimmt oder so den Pool zu transferieren? Was denkst du, ist da oben, da du wahrscheinlich mehr darüber weißt als ich dazu? Stilez vor 5 Jahren 0
Vielleicht habe ich missverstanden, was Sie damit gemeint haben: "... es sendet 35 TB, aber die 21 TB, die bereits gesendet wurden (deduierte Daten), gehen wirklich schnell, ..." grawity vor 5 Jahren 0
Ich meinte, dass ich erwartete, dass entweder (a) jeder logische Block nur einmal gesendet werden würde - das heißt, er sendet 14 TB und der Fortschrittszähler bei 14 TB (b), oder (b) würde jede Referenz für insgesamt 35 TB senden, aber alle Blöcke bereits gesendet würde, würde nur ein Zeiger gesendet werden, nicht die vollständigen Daten, so dass nur 14 TB seines "Count" aufgrund tatsächlicher Daten langsamer werden würden, die anderen 21 TB würden in der Fortschrittsinfo gezählt, würden aber nur als Zeiger / Duplikat vorbeifliegen Es mussten Block-IDs (nicht der tatsächliche Blockinhalt) für alle doppelten Blöcke gesendet werden. Daran habe ich gedacht / gedacht. Stilez vor 5 Jahren 0
Siehe Update auf OP. Stilez vor 5 Jahren 0

1 Antwort auf die Frage

1
Dan

Von dem, was Sie zur Komprimierung angesprochen haben, gehe ich davon aus, dass alle Speichergrößen / Geschwindigkeiten, die Sie beschrieben haben, unkomprimiert waren. Wenn dies nicht der Fall ist, können die Übertragungszeiten um einen Faktor verlängert werden, der dem durchschnittlichen Komprimierungsverhältnis entspricht (nicht jedoch, wenn der Plattenzugriff der Engpass ist, da die Dekomprimierung / Komprimierung nach dem Lesen von der Festplatte in zfs sendund vor dem Schreiben auf die Festplatte erfolgt zfs receive).

Basierend auf den bisher gesammelten Informationen klingt dies nach Engpässen bei der Festplattenbandbreite und nicht bei der Netzwerkverbindung. Sie haben erwähnt, dass jedes System mit ~ 500 MB / s lesen / schreiben kann. Daher ist Ihre Übertragungszeit für 35 TB im besten Fall etwa 20 Stunden (etwa 2,5-mal langsamer als nur das 10-Gbit / s-Netzwerk). Aber aufgrund Ihres Spiegelungs-Setups bin ich überrascht, dass Lesen und Schreiben denselben Durchsatz erzielen würden. Sind Sie sich dessen sicher? Auf dem Sendesystem müssen Sie nur von einer Platte lesen (um Lesevorgänge auf drei Platten parallelisieren zu können), auf dem Empfangssystem müssen Sie jedoch auf alle drei Festplatten schreiben (Sie sind also an den Durchsatz der langsamsten Festplatte gebunden.) zu einer bestimmten Zeit). Um den Schreibdurchsatz auf der Empfangsseite zu testen, können Sie ausführen dd if=/dev/urandom of=some_file_in_pool bs=1M count=1024 conv=fdatasync.

Da Sie sagten, dass die empfangenden Festplatten zu 100% ausgelastet sind, schätze ich, dass die Schreibbandbreite von 500 MB / s nicht erreicht wird. Dies kann entweder darauf zurückzuführen sein, dass das tatsächliche Schreiblimit niedriger ist als das (der ddBefehl sollte dies bestätigen), oder es könnte sein, dass das System während des Empfangs Metadaten lesen muss, was Ihre schöne Schreibarbeitslast mit großer IO beeinträchtigt durch das Hinzufügen einer Reihe von Disketten sucht die Mischung. Sie sollten in der Lage sein, die zweite Hypothese eingehender zu untersuchen, indem Sie DTrace verwenden, um zu ermitteln, was der ioAnbieter für Ihre Lese- / Schreibgröße hält.

Danke, ich habe mich noch nicht mit dtrace auseinandergesetzt (ich denke, Sie müssen nicht mehr über die Struktur / den Kernel wissen als ich). Wenn es einen bestimmten Liners / dtrace-Code gibt, der hier helfen kann, können Sie ihn vorschlagen, damit ich es ausprobieren kann? Da Sie nicht sicher sind, ob ich die DD-Geschwindigkeit während der Replikation testen kann? Zur Klarstellung läuft ja auch ein einzelner Spiegel auf der langsamsten aller Festplatten. Ein zfs-Pool mit 4 gestreiften Spiegeln kann jedoch auf alle 4 langsamsten Festplatten gleichzeitig schreiben (4 vdevs). Wenn also HDD IO die Grenze ist, sollte die maximale Gesamtgeschwindigkeit immer noch etwa 4x betragen, was auch immer eine einzelne Festplatte erreicht hätte. Das war der Gedanke, den ich bezüglich der Schreibgeschwindigkeit hatte. Stilez vor 5 Jahren 0
Die meiste Komprimierung im Quellpool stammt von der Deduplizierung - die hoch deduplizierten Daten sind etwa 2,6x. Im Gegensatz dazu ist die Komprimierung ein geringerer Faktor, nur etwa 1,17x. Möglicherweise nicht streng vergleichbar, da eine aus der zpool-Liste und die andere aus der ZFS-Liste im Hauptdatensatz (90% des Pools) entnommen wird, sie gibt jedoch eine Idee. Stilez vor 5 Jahren 0
Ja, Sie haben recht, das Striping hilft, obwohl es keine Garantie gibt, dass IOs gleichmäßig über die Streifen verteilt werden. Der einfachste Weg, um ein gutes Gefühl zu bekommen, besteht darin, es einfach zu messen. Ja, die Ergebnisse werden durch das laufende Senden oder Empfangen beeinflusst (aber wenn die Spezifikationen jedes Systems gleich sind, können Sie es stattdessen auf der Sendeseite ausführen). Der einfachste Start für DTrace ist das DTraceToolkit, das hier verfügbar ist: https://github.com/opendtrace/toolkit/blob/master/Docs/Contents. Klänge wie die Komprimierung sollten keinen großen Einfluss auf die Leistung haben. Dan vor 5 Jahren 0
Noch ein letzter Gedanke: Ich denke, dass Dedup beim Senden / Empfangen nicht genauso funktioniert wie ein poolweites Dedup - im Prinzip sind Dedup-Blöcke im Sendestrom enthalten, aber die Empfangsseite muss immer noch die Dedup-Tabelle des Pools von Grund auf wiederherstellen (IIRC) . Dies könnte für die von mir erwähnten Direktzugriffs-Metadaten verantwortlich sein, wenn die Dedup-Tabelle nicht in den Arbeitsspeicher passt. Die dd-Arbeitslast mit zufälligen Daten hätte auch diese Einschränkung, so dass es immer noch eine gute Möglichkeit ist, eine empfangsähnliche Arbeitslast zum Testen zu replizieren. Dan vor 5 Jahren 0
Der RAM ist so berechnet, dass er die vollständige Dedup-Tabelle und weitere 50 GB Cache / Metadaten sowie die Metadaten enthält, die von ARC sysctl verwendet werden, um sicherzustellen, dass genügend RAM reserviert ist (85 G), sodass Dedupl-Tabellen nicht geräumt werden. Ich habe die Dedup-Größe in RAM berechnet, es sind etwa 40 G (2,5-3 GB pro TB). Ich habe mir dtrace angesehen und überlegt, wie ich das tun könnte, was Sie vorschlagen, ohne ein bisschen mehr Wissen. Irgendwelche Chance auf einen Skript-Hinweis, den ich diesmal nutzen kann und von / lernen kann? Stilez vor 5 Jahren 0
Siehe Update auf OP. Stilez vor 5 Jahren 0
Der Grund, warum ich nicht zu viele Details zum Untersuchen kleiner IOs geben möchte, die Ihr schönes Streaming zerstören, ist, dass es nicht wirklich etwas gibt, was Sie tun können, um das Problem zu beheben. Ich hatte jedoch einen abschließenden Gedanken, der hilfreich sein könnte. Dieser ist hier geschrieben: http://everycity.co.uk/alasdair/2010/07/using-mbuffer-to-speed-up-slow-zfs-send- zfs-receive / Dan vor 5 Jahren 0