Ich habe jetzt heute mal testweise einen Z2 Pool mit allen 12 Platten errichtet. Wenn ich darauf Nullen schreiben will mit
Code:
dd if=/dev/zero of=dd.tmp bs=2M count=20000
, dann schafft die Kiste gerade so mal 30MB/s im gesamten Pool! Nicht pro Platte. Der Fehler war auch schnell gefunden; die CPU war mit 20 Kernen überall komplett am Anschlag.
Dann habe ich einen neuen stripped Pool mit 2x 6 Platten jeweils im Z2 erstellt und ich habe eine enorm hohe Schreibrate und die CPU langweilt sich. Damit kann ich 100GB in ca. 44 Sekunden schreiben (ca. 2250MB/s).
Kann mir das einer erklären, warum das so ist??
Und vor allem: Warum ist die CPU load beim stripped Z2
ohne lz4 Compression bei ca. 90% pro Kern und
mit lz4 Compression kaum vorhanden??
Für mein Verständnis hätte die CPU mit aktivierter Kompression ja viel mehr zu tun, also mit deaktivierter Kompression??
Naja, einmal solltest du beim stripped Pool die doppelte Schreibrate haben. Und dann kann die Kompression schon viel ausmachen. LZ4 ist echt super und beschleunigt das System sogar meistens. Bei LZ4 guckt sich der Algorithmus die ersten paar Prozent einer Datei an. Wenn der dann meint da lässt sich kaum was mit Kompression rausholen, z.B. weil das vermutlich eine bereits komprimierte Datei ist, dann lässt LZ4 das Komprimieren einfach weg und es wird kaum CPU-Power benötigt. Lohnt sich das Komprimieren, dann hat es einen sehr effizienten Algorithmus der zwar nicht so super krass komprimieren kann, aber dafür auch sehr wenig auf die CPU geht. Super ist LZ4 z.B. wenn du eine IMG-/ISO-Datei speichern willst. Oft ist da die Datei z.B. 700MB groß aber echte Daten sind nur 100MB vorhanden und 600MB sind einfach Nullen. Diese Nullen lassen sich beim Komprimieren einfach "wegwerfen" und komprimiert ist die Datei dann nur noch 100MB oder kleiner.
Wenn man die Datei fast ohne Aufwand auf 1/7 der Größe komprimiert bekommt, dann muss ZFS auch entsprechend weniger auf die HDDs schreiben und die Schreibrate versiebenfacht sich im Vergleich zum Pool ohne Kompression der die vollen 700MB auf die HDDs schreiben müsste.
Mit
dd if=/dev/zero of=dd.tmp bs=2M count=20000
hast du ja quasi eine perfekt komprimierbare Datei erstellt und wenn sich die 2MB Datei aus Nullen auf wenige KB komprimieren lässt, dann wird ja in der Summe auch fast nichts auf die HDDs geschrieben und die Schreibleistung ist enorm. Würdest du das gleiche mit Zufallszahlen statt Nullen (
dd if=/dev/urandom of=dd.tmp bs=2M count=20000
) versuchen würde es ganz anders ausgehen.
Da solltest du aber mal der Sache auf den Grund gehen, warum du nur 30MB/s ohne Kompression schaffst bzw. warum ZFS so einen krassen Overhead hat, dass da 20 Cores voll ausgelastet werden. Bei meinem Raidz1 mit 4x 8TB mit lz4 und Verschlüsselung kommen meine 4 Cores bei normalen Dateien meistens nur so auf 8% Auslastung. Irgendwas läuft da also falsch.
Mal die wichtigsten ZFS Optionen bezüglich Leistung:
1.) "sync=standard": erlaubt Sync Writes aber erzwingt/ignoriert diese nicht, so dass da die Software entscheiden kann, ob sie Sync Writes braucht oder Async auch reicht. Sync Writes machen alles extrem lahm und verursachen massig Wearing bei den SSDs, da alles doppelt auch die Laufwerke geschrieben werden muss (wenn keine extra SLOG-SSD vorhanden) und kein RAM-Caching geht. Man könnte da auch "sync=disabled" nehmen, dann würden alle Sync Writes einfach als Async Writes behandelt werden und alles wäre schneller. Ist da aber mal Strom weg oder der Kernel crasht, dann verlierst du auch Daten die eigentlich hätten sicher sein sollen, da das Programm denkt sie wären synchron gespeichert worden, was sie aber nicht sind und so mit dem flüchtigen RAM verloren gingen. Würde ich generell nicht raten zu tun am NAS. "sync=always" hingegen würde alle Async Writes als Sync Writes behandeln und damit die Sicherheit erhöhen aber alles auch extrem ausbremsen.
2.) "compression=lz4": Da würde ich eigentlich immer "lz4" nehmen und nie "off". LZ4 ist so effizient, dass es fast immer den Pool schneller macht. Selbst schneller als unkomprimiert, da der niedrige Kompressionsaufwand weniger bremst als was die geringere Dateigröße dann wieder beschleunigt. Ggf. wäre das neue "zstd" auch eine Option. Ich weiß allerdings nicht ob das inzwischen schon in TrueNAS 12.0 implementiert ist. Das wäre wohl so ein Zwischending aus der Geschwindigkeit von LZ4 und der besseren Kompressionsrate von gzip.
3.) "atime=off" und "relatime=off": Gerade bei SSDs oder wenn eine Datenbank mit vielen kleinen Schreibvorgängen läuft zu empfehlen. Mit der Einstellung müssen bei jedem Dateizugriff nicht erst die Metadaten aktualisiert werden, was sonst bei jeder Leseoperation auch eine Schreiboperation ausführen würde. Wenn man nur "relatime" aktiviert, dann sollte der zwar Zugriffszeiten schreiben, aber maximal 1 mal die Minute oder so.
4.) Dann wäre da noch die Verschlüsselung. Aktiviert sollte es ausbremsen, aber wenn die CPU AES-NI kann (und in den VM-Einstellungen das CPU Flag dafür gesetzt ist) dann geht dies wenigstens kaum auf die CPU und macht sich daher bei HDDs nicht groß bemerkbar. Bei SSDs kann das schon wieder anders aussehen, die schaffen ja ganz andere Geschwindigkeiten. Aber bei AES schaffen CPUs meist schon einige tausend MB/s. Ich glaube FreeNAS 11.3 konnte dir da auch ein Benchmark der Verschlüsselungsalgorithmen machen, um zu testen, was bei dir am schnellsten laufen würde.
5.) Die Deduplikation macht fast nie Sinn, außer man hat spezielle Fälle wie ein eigenes Dataset für eine Datenbank wo immer und immer wieder die gleichen Werte geschrieben werden müssen. Deduplikation braucht massig RAM (Faustformel 5GB pro 1TB Rohkapazität) und viel CPU-Zeit.
Dann gibt es noch 4 Arten wie du mit extra Hardware deinen HDD-Pool schneller machen kannst:
1.) Mehr RAM kaufen damit dein ARC größer sein kann. Je mehr RAM du ZFS gibst, desto mehr kann es cachen und desto besser die Leserate.
2.) Sollte der RAM sich nicht mehr erweitern lassen, dann könnte man dem Pool eine SSD als L2ARC hinzufügen. Damit würde das Cachen dann auch vom RAM auf die L2ARC-SSD ausgeweitet werden. Also ähnlich wie swap.
3.) Hat man viele Sync Writes kann man über eine zusätzliche SLOG-SSD nachdenken. Damit würden alle Sync Writes erst auf die schnelle SLOG-SSD geschrieben werden und später dann auf die HDDs. Ohne SLOG liegt das ZIL auf den HDDs und alles würde erst auf die HDDs geschrieben, dann später von den HDDs gelesen werden, um es dann noch einmal richtig auf die HDDs zu schreiben. Das kann schon sehr die Schreibrate erhöhen, aber halt auch echt nur für Sync Writes. Das meiste was man am NAS hat sollten Async Writes sein und da hilft ein SLOG auch nichts.
4.) Man kann dem Pool eine SSD als Special Device hinzufügen. Dann werden die vielen kleinen Metadaten nicht mehr auf den HDDs gespeichert sondern auf der schnelleren SSD. Das kann dann gesamt die Geschwindigkeit erhöhen.
Aber nicht vergessen auch hier auf Parität zu setzen. Fällt eine SSD aus dann ist der ganze Pool kaputt und alles auf den HDDs ist auch verloren. Da nimmt man dann besser auch gleich 2 oder 3 von. Und SSDs können von ZFS sehr schnell kaputt geschrieben werden, wenn man nicht gerade SSDs mit SLC Flash nimmt.