ZFS für stoßweises sequentielles Schreiben optimieren

ZFS für stoßweises sequentielles Schreiben optimieren

Dies ist eine Fortsetzung von:Schnelle Netzwerkschreibvorgänge mit Speicher großer Kapazität. Das Setup hat sich deutlich verändert.

Ich habe einen Pool mit einem einzelnen raid-z2Laufwerk mit 6 Laufwerken, alles Exos X18 CMR-Laufwerke. Durch fiomanuelle Tests weiß ich, dass das Array durchschnittlich etwa 800 MB/s sequentielle Schreibvorgänge aushält. Das ist in Ordnung und entspricht der erwarteten Leistung dieses Arrays. Die Maschine ist ein Ryzen5 Pro 2400 GE (4C/8T, 3,8 GHz Boost) mit 32G ECC RAM, NVMe-Boot-/Systemlaufwerk und 2x10Gbps Ethernet-Ports (Intel x550-T2). Ich verwende ein aktuelles Arch-System mit zfs 2.1.2-1.

Mein Anwendungsfall ist ein Videoarchiv mit meist großen (~30 G) komprimierten Videos, die einmal geschrieben und einmal gelesen werden. Ich habe deaktiviert atime, gesetzt recordsize=1M, gesetzt compressios=offund gesetzt, dedup=offda die Daten eigentlich nicht komprimierbar sind und Tests trotz der Angaben im Internet eine schlechtere Leistung mit compression=lz4als offgezeigt haben und es absichtlich keine doppelten Daten gibt. Dieser Pool wird über das Netzwerk via Samba geteilt. Ich habe mein Netzwerk und Samba so weit optimiert, dass die Übertragung von NVMe NTFS auf einem Windows-Rechner zu NVMe ext4 1 GB/s erreicht, also ziemlich nahe daran ist, die 10-Gbit/s-Verbindung mit 9K Jumbo Frames zu sättigen.

Hier stoße ich auf Probleme. Ich möchte ein ganzes 30-G-Videoarchiv mit 1 GB/s auf das raid-z2Array übertragen können, das nur 800 MB/s sequentielles Schreiben unterstützt. Mein Plan ist, die RAM-basierten Dirty Pages zu verwenden, um den Überlauf zu absorbieren und ihn auf die Festplatte zu spülen, nachdem die Übertragung auf der Clientseite „abgeschlossen“ ist. Ich dachte, dass ich nur Dirty Pages (1024-800)*30~=7Gim RAM brauche, die innerhalb von ca. 10 Sekunden nach Abschluss der Übertragung auf die Festplatte geschwemmt werden können. Ich verstehe die Auswirkungen auf die Datenintegrität und das Risiko ist akzeptabel, da ich die Datei später bis zu einem Monat lang immer noch einmal übertragen kann, falls ein Stromausfall dazu führt, dass die Datei verloren geht oder unvollständig ist.

Ich kann ZFS jedoch nicht dazu bringen, sich wie erwartet zu verhalten ... Ich habe meine /etc/modprobe.d/zfs.confDatei folgendermaßen bearbeitet:

options zfs zfs_dirty_data_max_max=25769803776
options zfs zfs_dirty_data_max_max_percent=50
options zfs zfs_dirty_data_max=25769803776
options zfs zfs_dirty_data_max_percent=50
options zfs zfs_delay_min_dirty_percent=80

Ich habe den entsprechenden Befehl ausgeführt, mkinitcpio -Pum mein Initramfs zu aktualisieren, und bestätigt, dass die Einstellungen nach einem Neustart angewendet wurden:

# arc_summary | grep dirty_data
        zfs_dirty_data_max                                   25769803776
        zfs_dirty_data_max_max                               25769803776
        zfs_dirty_data_max_max_percent                                50
        zfs_dirty_data_max_percent                                    50
        zfs_dirty_data_sync_percent                                   20

D. h. ich stelle die maximale Anzahl schmutziger Seiten auf 24 G ein, was viel mehr ist als die 7 G, die ich benötige, und warte, bis 80 % davon verbraucht sind, um Schreibvorgänge zu verzögern. Soweit ich weiß, sollte der Pool 19 G in den RAM aufnehmen können, bevor er Schreibvorgänge vom Client (Samba) mit Verzögerung zurückdrängt.

Was ich jedoch beim Schreiben vom Windows-Client aus beobachte, ist, dass die Schreibleistung nach etwa 16 Sekunden bei einer Schreibgeschwindigkeit von ~1 GB/s schlagartig abfällt (es iostatist immer noch zu sehen, dass die Festplatten hart daran arbeiten, die Daten zu löschen), was ich nur als Pushback-Mechanismus für die Schreibdrosselung von ZFS bezeichnen kann. Das ergibt jedoch keinen Sinn, denn selbst wenn während der 16 Sekunden nichts gelöscht wurde, hätte es 3 Sekunden später einsetzen müssen. Außerdem fällt es am Ende noch einmal ab, siehe Bild: [ Bildbeschreibung hier eingeben][https://i.stack.imgur.com/Yd9WH.png]

Ich habe versucht, den zfs_dirty_data_sync_percentSchreibvorgang früher einzustellen, da der Dirty-Page-Puffer so viel größer als der Standard ist. Außerdem habe ich versucht, die aktive E/A-Skalierung so einzustellen, dass sie zfs_vdev_async_write_active_{min,max}_dirty_percentfrüher einsetzt, damit die Schreibvorgänge mit dem großen Dirty-Puffer schneller auf Touren kommen. Beides hat die Position der Klippe nur leicht verschoben, aber nicht annähernd so, wie ich es erwartet hatte.

Fragen:

  1. Habe ich die Funktionsweise der Schreibdrosselungsverzögerung missverstanden?
  2. Ist das, was ich versuche, möglich?
  3. Wenn ja, was mache ich falsch?

Ja, ich weiß, ich jage buchstäblich ein paar Sekunden hinterher und werde den Aufwand, der dafür aufgewendet wurde, nie wieder hereinholen. Das ist ok, es ist an diesem Punkt eine persönliche Angelegenheit zwischen mir und ZFS und eine Grundsatzfrage ;)

Antwort1

Sie müssen zfs_txg_timeoutden Parameter auch vom aktuellen Standardwert von 5 Sekunden auf etwa 7 G/0,2 G/s = 35 s erhöhen, sodass eine Einstellung auf 40 s ausreichen sollte.

In deinem /etc/modprobe.d/zfs.conf:

options zfs zfs_txg_timeout=40

Beachten Sie, dass der ARC genau das ist: ein „Lese“-Cache ohne Zugriff auf den Schreibcache. Stellen Sie daher sicher, dass Ihr ARC nicht so eingerichtet ist, dass er die zusätzlichen 7 G+ an Daten verbraucht, die Ihr Blockschreibcache pro 30 GB Schreibstrom aufnehmen muss. Der Schreibcache für ZFS ist wie jeder andere einfache Blockschreibcache (wie der commitParameter für ext4-Dateisysteme). Führen Sie daher unbedingt Tests außerhalb der Produktion durch, um sicherzustellen, dass während aller Übertragungsszenarien kein RAM-Mangel auftritt.

Antwort2

Jeder Schreibvorgang aktualisiert den ARC, wenn zfs primarycache = all (Standard). Wenn die Leselatenz für die Daten, die Sie gerade schreiben, unwichtig ist, schlage ich vor, zfs primarycache=meta einzustellen.

Antwort3

Sie verfügen derzeit nicht über genügend RAM oder Speicherressourcen für das, was Sie suchen.

Planen Sie auf der Grundlage Ihres gewünschten E/A-Durchsatzes und der Leistung im schlimmsten Fall.

Wenn Sie für den beschriebenen Arbeitsdatensatz unter allen Bedingungen einen Durchsatz von 1 GB/s benötigen, stellen Sie sicher, dass die Anzahl der Festplattenspindeln oder der Schnittstellendurchsatz dies unterstützt.

verwandte Informationen