ZFS best practice für Enterprise NVMEs

D

Deleted member 116138

Guest
Moin zusammen.

Ich stelle mir gerade die Hardware für einen neuen PVE zusammen. AMD Epyc mit 512GB RAM, 2x Samsung PM1643 (RAID1 für das OS) und 4x Samsung PM1735 3,6TB.

Auf dem PVE sollen lediglich 2x Windows Server VMs laufen, die jedoch relativ viel R/W Leistung benötigen (DMS und SQL). Hierfür möchte ich die 4 Stück PM1735 verwenden.

Wie sieht denn die aktuelle best practice für die RAID-Konfiguration aus? Man findet zuhauf Threads, die ZFS RAID10 vs. ZFSz2 vergleichen und dort die Meinungen teils stark auseindergehen. Auch beim Thema zum Konfigurieren von „ashift“ & Co gibt es unterschiedliche Philosophien. z2 wäre m. W. nach ausfallsicherer.

Es wäre auch kein Problem, von 4 auf 6 Stück NVME zu erhöhen.

Danke im Voraus für jedwede Tipps.
 
Das ist halt echt schwer zu sagen. Hat alles seine Vor- und Nachteile.

Ashift=9 macht für SSDs eigentlich keinen Sinn. Und ashift=13 oder mehr wird halt auch sehr schnell sehr kritisch, da du deine Volblocksize ja nicht nach belieben erhöhen kannst. Und je größere deine ashift ist, desto größer muss auch deine Volblocksize werden. Hast du SQL als Workload machst du ja 16K Sync Writes mit massig Write Amplification. Deine Volblocksize sollte dann 16K nicht überschreiten, weil es echt übel kommt mit einer größeren Blockgröße auf eine kleinere Blockgröße zuzugreifen. Bei raidz2 willst du aber eigentlich immer wenigestens 4x deine minimale Blockgröße haben, welche ja durch dein ashift definiert wird. Mit ashift=12 wären das 4K, also 4x 4K = 16K volblocksize und das wäre für SQL ok. mit ashift=13 wären es 8K, also 4x 8K = 32K volblocksize und das möchte man dann wegen SQL schon wieder nicht. Mit raid10 bei 4 disks würde ashift=13 aber schon wieder gehen, da die volblocksize dort 2x deine minimale Blockgröße sein sollte. 2x 8K = 16K volblocksize wären dann wieder ok für SQL.

Und bei RAID10 vs Raidz2 ist halt die Frage ob du eher wert auf Performance oder Ausfallsicherheit legst. Mit Raid10 solltest du theoretisch die doppelten IOPS schaffen, was ja für DBs nicht unwichtig ist. Bei Raidz2 dürfen dir aber 2 beliebige Disks ausfallen. Bei Raid10 dürfen dir nur 1-2 Disks ausfallen. Fallen die Disks in der richtigen Kombination aus verträgt auch dein Raid10 zwei ausgefallene Disks. Fallen jedoch mit Pech zwei Disks des selben Mirrors aus sind halt alle Daten weg.
Du meintest ja es würden auch 6 Disks gehen. Dann könnte man z.B. auch zwei 3-Wege-Spiegelungen haben und die dann Stripen (geht aber nur manuell und ist daher nichts für den PVE Installer als Bootlaufwerke, könnte man aber später einrichten falls du 6 Disks hast die ausschließlich als VM Storage genutzt werden sollen). Damit hättest du dann die selben (beim Lesen sogar bessere) IOPS wie ein Raid10 aus 4 Disks und es dürften 2-4 Disks ausfallen. Wäre also auch gleichzeitig noch besser von der Ausfallsicherheit als ein Raidz2 aus 4 Disks.
Da kombinierst du dann die Vorteile von beiden und übertrumpfst sogar beide noch, brauchst aber halt auch zwei zusätzliche Disks.

In der Theorie sollte das so aussehen wenn ich mich da nicht irre (bitte mich sonst korrigieren):
Minimale sinnvolle Volblocksize bei ashift=12:Kapazität:IOPS Lesen:IOPS Schreiben:Throughput Lesen:Throughput Schreiben:veträgt ausgefallene Disks:
4 Disk Raid10:8K2x4x2x4x2x1-2
4 Disk Raidz2:16K< 2x1x1x2x2x2
6 Disk Raid10:8K oder besser 16K (12K geht nicht)3x6x3x6x3x1-3
6 Disk Raidz2:16K4x1x1x4x4x2
6 Disk Striped 3-Way-Mirrors:8K2x6x2x6x2x2-4
 
Last edited:
Fast alles richtig, aber MS SQL mach geschätzt seit 10+ Jahren 64k. Deshalb auch die Empfehlung von Microsoft, NTFS mit 64k formatieren.
 
Erstmal vielen Dank für Deine ausführliche Antwort.

Der PVE selbst soll auf 2x Pm1643 im RAID1 laufen. Für die beiden VMs würde ich 6 Stück PM1735 exklusiv verwenden.

Wie lässt sich denn der 3-way-mirror als stripe konfigurieren? Gibt es dazu ein howto? Über die GUI des PVE wird das ja wahrscheinlich nicht funktionieren?
 
Der PVE selbst soll auf 2x Pm1643 im RAID1 laufen. Für die beiden VMs würde ich 6 Stück PM1735 exklusiv verwenden.
Dann wäre es kein Problem einen etwas exotischeres Pool-Layout für die VMs zu verwenden.
Wie lässt sich denn der 3-way-mirror als stripe konfigurieren? Gibt es dazu ein howto? Über die GUI des PVE wird das ja wahrscheinlich nicht funktionieren?
Ist relativ einfach.
1.) mit ls -l /dev/disk/by-id/ herausfinden was die IDs deiner SSDs sind die du nutzen willst. Ist dann sowas wie "/dev/disk/by-id/ata-INTEL_SSDSC2BA200G4_BTHV636205M3200MGN" und sollte der "/dev/sdX" Variante vorgezogen werden, weil du dann einfacher siehst welche SSD mit welcher Seriennummer denn wirklich gemeint ist, falls da z.B. mal eine ausfällt und du die austauschen musst. Außerdem ist das immer eindeutig und verweist auf die richtige SSD, selbst wenn die selbe SSD die Bezeichnund wechselt und z.B. mal als "/dev/sda" und mal als "/dev/sdb" erkannt wird.
2.) So einen Pool wo man zwei 3-fach-Spiegel stripet kann man mit einem Befehl wie dem hier erstellen:
zpool create -f -o ashift=12 DeinPoolWunschname mirror /dev/disk/by-id/SSD1 /dev/disk/by-id/SSD2 /dev/disk/by-id/SSD3 mirror /dev/disk/by-id/SSD4 /dev/disk/by-id/SSD5 /dev/disk/by-id/SSD6
3.) Mit zpool status kannst du dann gucken ob der Pool korrekt erstellt wurde und alles ok ist
4.) Dann ist es wichtig, dass dein Pool nie voller als 90% beschrieben wird, weil der sonst in den Panik-Modus geht. Ab grob 80% wird der Pool langsam. Ich würde da also raten für den kompletten Pool gleich zu Begin ein 80-90% Quota zu setzen, dass man garnicht erst ausversehen mehr draufschreiben kann. Da guckst du erst mit zfs list wie groß dein Pool ist, multiplizierst die Größe mit 0,8 oder 0,9 und das Ergebnis setzt du dann so als Quota für den Pool: zfs set quota=1234g DeinPoolWusnchname
5.) danach würde ich für den VM-Storage ein neues Dataset erstellen: zfs create DeinPoolWunschname/VMs
6.) dann am besten noch nach belieben dein Dataset optimieren. Ich würde z.B. atime deaktivieren oder relatime aktivieren: zfs set atime=off DeinPoolWunschname/VMs ODER zfs set relatime=on DeinPoolWunschname/VMs + zfs set atime=on DeinPoolWunschname/VMs.
Falls du die Kompression wechseln willst, oder Deduplication/Veschlüsselung nutzen willst würde ich das auch jetzt direkt machen, bevor du deine ersten Daten schreibst, weil eine Änderung nicht rückwirkend auf bestehende Daten angewendet werden kann.
7.) Dann ins PVE WebUI gehen und unter "Datacenter -> Storage -> Add -> ZFS" dein eben erstelltes Dataset als Storage hinzufügen. Für "ZFS Pool" dann "DeinPoolWunschname/VMs" wählen, für "ID" kannst du dir was beliebiges aussuchen wie "VM-Storage", die "Thin Provisioning" Checkbox würde ich setzen damit die VMs keinen Platz verschwenden und dann ganz wichtig unter "Block Size" den Wert eintragen, welcher als "volbocksize" benutzt werden soll. Den musst du dir halt ausrechnen. Am besten wäre wohl 2x die Blockgröße deines Pools. Also 8K falls ashift=12 verwendet wurde, 16K falls ashift=13, 32K falls ashift=14 usw.
8.) Jetzt sollte dein VM Storage laufen und dir von PVE beim Erstellen von VMs vorgeschlagen werden. Wenn du verschiedenes testen willst kannst du mit fio benchmarks machen und einfach verschiedenste Pool-Layouts austesten und vergleichen und dann das nehmen, was dir am meisten zusagt. Da du für das System einen eignenen ZFS Pool hast, kannst du da ja nach belieben deinen VM-Pool zerstören und neu erstellen, ohne da immer PVE neu installieren zu müssen.
Fast alles richtig, aber MS SQL mach geschätzt seit 10+ Jahren 64k. Deshalb auch die Empfehlung von Microsoft, NTFS mit 64k formatieren.
Ah ok. Ich hatte bisher immer nur MySQL/MariaDB benutzt. Die wollen ja 16K.

Edit:
Achso, und später beim Erstellen der VMs nicht vergessen "virtio SCSI single" zu benutzen. Und da dann die "Discard", "SSD Emulation" und "io thread" Checkboxen aktivieren, damit das mit dem Thin-Provisioning auch richtig klappt, um das das meiste aus dem Storage herauszuholen. CPU typ würde ich auch von "kvm64" auf "host" ändern sofern du nicht zwischen mehreren Nodes im Cluster migrieren willst. Und als Cache ist eigentlich "none" empfehlenswert damit der Host nicht mehrfach cachen muss, da ZFS ja schon den ARC zum cachen nimmt. Und für die virtuelle NIC wäre auch virtio empfehlenswert für bessere Performance.
 
Last edited:
  • Like
Reactions: proNET and at3tb
Super!

vielen Dank, ich werde das mal testen und berichten.

Noch einen sonnigen Sonntag :cool:
 
Nach langen Tests (weil ich den Luxus hatte, die Server erst spät produktiv in Betrieb nehmen zu müssen) hier meine Erfahrungen aus diversen Testszenarios.

ZFS Tuning

Ein guter Einstiegspunkt ist die Doku von OpenZFS bzgl. des "Tunings":

Link zum offiziellen RTD

NVME low-level Formatierung

Einen merklichen Unterschied hat die low-level Formatierung auf die für die NVMe optimale Sektorengröße gebracht. Mittels smartctl -a kann der optimale Wert ermittelt werden. Man sollte via

Code:
apt install nvme-cli

die NVME Tools vorab installieren. Für die PM1735 (als Beispiel mit nvme0n1 angegeben) gibt

Code:
smartctl -a /dev/nvme0n1

folgendes aus:

Supported LBA Sizes (NSID 0x1) Id Fmt Data Metadt Rel_Perf 0 - 512 0 1 1 - 512 8 3 2 + 4096 0 0 3 - 4096 8 2 4 - 4096 64 3

Die erste Spalte "ID" gefolgt von "Fmt" markiert mit dem Plus-Zeichen die aktuell verwendete Formatierung. "Rel_Perf" indiziert das Performance Level, wobei die 0 den idealen Wert darstellt (lower is better).

Mit

Code:
nvme format /dev/nvme0n1 -l 2

wird die NVMe auf den idealen Wert formatiert (Datenverlust natürlich inklusive).

Zusätzliche NVMe als Special Device oder SLOG/Cache

Dies habe ich ebenfalls getestet und es hat keinen merklichen Unterschied gebracht. Hierfür hatte ich jeweils 2 NVMe mit nahezu identischen Werten gegenüber den PM1735 im RAID1 als Special Device und später noch als SLOG/Cache verwendet. Solange die zusätzlichen NVMe das bestehende RAID nicht wesentlich übertreffen, gab bzw. gibt es hier keine besonderen Vorteile. Anders sieht es aus, wenn man NVMe als Special Device für ein SSD-RAID verwendet, da diese wesentliche geringere Durchsätze haben.

Unterschiedliche Datasets & Blockgrößen

Ich hatte mir unterschiedliche Datasets für die VMs erstellt. Die 08/15 Windows VMs ohne Datenbankapplikationen oder sonstigen R/W-Ops, welche viele kleine Daten schreiben, haben auf Thin provisioned 128k Blocksize bisher die beste Performance gezeigt. *NIX Systeme hingegen auf Thin provisioned mit 8k bzw. 16k.

P.S.: nochmal vielen Dank an @Dunuin für seine Hilfe.
 
Last edited by a moderator:

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!