ZFS unter Linux - L2ARC wird nicht gelesen

ZFS unter Linux - L2ARC wird nicht gelesen

Heute habe ich einige Tests mit L2ARC unter Verwendung des neuesten ZFS unter Linux 0.7.10 durchgeführt. Ich habe gesehen, dass L2ARC mit Daten gefüllt wird, aber mit den Standardmoduleinstellungen werden die im L2ARC-Cache gespeicherten Daten nie berührt. Stattdessen werden die Daten aus den vdevs des Hauptpools gelesen. Ich habe dieses Verhalten auch in 0.7.9 gesehen und bin mir nicht sicher, ob dies das erwartete Verhalten ist.
Selbst wenn dies das erwartete Verhalten wäre, finde ich es seltsam, L2ARC mit Daten zu verderben, die nie gelesen werden.


Die Testinstallation ist eine VM:

  • CentOS 7.5 mit den neuesten Patches
  • ZFS unter Linux 0.7.10
  • 2 GB RAM

Ich habe einige ZFS-Einstellungen vorgenommen:

  • l2arc_headroom=1024und l2arc_headroom=1024zur Beschleunigung der L2ARC-Population

So wurde der Pool erstellt und gestaltet. Ich weiß, dass das für eine reale Konfiguration ziemlich seltsam ist, aber es war nur für L2ARC-Tests gedacht.

[root@host ~]# zpool create tank raidz2 /dev/sda /dev/sdb /dev/sdc cache sdd -f
[root@host ~]# zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  2.95G   333K  2.95G         -     0%     0%  1.00x  ONLINE  -
  raidz2  2.95G   333K  2.95G         -     0%     0%
    sda      -      -      -         -      -      -
    sdb      -      -      -         -      -      -
    sdc      -      -      -         -      -      -
cache      -      -      -         -      -      -
  sdd  1010M    512  1009M         -     0%     0%

Schreiben Sie jetzt einige Daten in eine Datei und sehen Sie sich die Gerätenutzung an.

[root@host ~]# dd if=/dev/urandom of=/tank/testfile bs=1M count=512
512+0 records in
512+0 records out
536870912 bytes (537 MB) copied, 9.03607 s, 59.4 MB/s

[root@host ~]# zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  2.95G  1.50G  1.45G         -    10%    50%  1.00x  ONLINE  -
  raidz2  2.95G  1.50G  1.45G         -    10%    50%
    sda      -      -      -         -      -      -
    sdb      -      -      -         -      -      -
    sdc      -      -      -         -      -      -
cache      -      -      -         -      -      -
  sdd  1010M   208M   801M         -     0%    20%

Okay, einige der Daten wurden bereits ins L2ARC verschoben, aber nicht alle. Lesen Sie sie also noch ein paar Mal ein, um sie vollständig ins L2ARC zu übertragen.

[root@host ~]# dd if=/tank/testfile of=/dev/null bs=512 # until L2ARC is populated with the 512MB testfile

[root@host ~]# zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  2.95G  1.50G  1.45G         -    11%    50%  1.00x  ONLINE  -
  raidz2  2.95G  1.50G  1.45G         -    11%    50%
    sda      -      -      -         -      -      -
    sdb      -      -      -         -      -      -
    sdc      -      -      -         -      -      -
cache      -      -      -         -      -      -
  sdd  1010M   512M   498M         -     0%    50%

Okay, L2ARC ist gefüllt und bereit zum Lesen. Aber man muss zuerst L1ARC loswerden. Ich habe Folgendes getan, was anscheinend funktioniert hat.

[root@host ~]# echo $((64*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; echo $((1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; arc_summary.py -p1

------------------------------------------------------------------------
ZFS Subsystem Report                        Sun Sep 09 17:03:55 2018
ARC Summary: (HEALTHY)
    Memory Throttle Count:                  0

ARC Misc:
    Deleted:                                20
    Mutex Misses:                           0
    Evict Skips:                            1

ARC Size:                           0.17%   1.75    MiB
    Target Size: (Adaptive)         100.00% 1.00    GiB
    Min Size (Hard Limit):          6.10%   62.48   MiB
    Max Size (High Water):          16:1    1.00    GiB

ARC Size Breakdown:
    Recently Used Cache Size:       96.06%  1.32    MiB
    Frequently Used Cache Size:     3.94%   55.50   KiB

ARC Hash Breakdown:
    Elements Max:                           48
    Elements Current:               100.00% 48
    Collisions:                             0
    Chain Max:                              0
    Chains:                                 0

Okay, jetzt sind wir bereit, vom L2ARC zu lesen (entschuldigen Sie die lange Einleitung, aber ich dachte, das wäre wichtig). Ich
habe den Befehl also noch einmal ausgeführt und in einem zweiten Terminal dd if=/tank/testfile of=/dev/null bs=512zugesehen .zpool iostat -v 5

Zu meiner Überraschung wurde die Datei von den normalen vdevs statt von L2ARC gelesen, obwohl die Datei in L2ARC liegt. Dies ist die einzige Datei im Dateisystem und während meiner Tests ist keine andere Aktivität aktiv.

              capacity     operations     bandwidth 
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank        1.50G  1.45G    736     55  91.9M  96.0K
  raidz2    1.50G  1.45G    736     55  91.9M  96.0K
    sda         -      -    247     18  30.9M  32.0K
    sdb         -      -    238     18  29.8M  32.0K
    sdc         -      -    250     18  31.2M  32.0K
cache           -      -      -      -      -      -
  sdd        512M   498M      0      1  85.2K  1.10K
----------  -----  -----  -----  -----  -----  -----

zfetch_array_rd_szIch habe dann an einigen Einstellungen wie , zfetch_max_distance, zfetch_max_streams, l2arc_write_boostund herumgespielt l2arc_write_maxund sie auf eine ungerade hohe Zahl gesetzt. Aber es hat sich nichts geändert.

Nach dem Wechsel

  • l2arc_noprefetch=0(Standard ist 1)
  • oder zfs_prefetch_disable=1(Standard ist 0)
  • beide von ihren Standardeinstellungen umschalten

Die Lesevorgänge werden vom L2ARC ausgeführt. Führen Sie es erneut in einem zweiten Terminal aus, dd if=/tank/testfile of=/dev/null bs=512beobachten Sie zpool iostat -v 5es und entfernen Sie L1ARC.

[root@host ~]# echo 0 > /sys/module/zfs/parameters/l2arc_noprefetch 
[root@host ~]# echo $((64*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; echo $((1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; arc_summary.py -p1
...
[root@host ~]# dd if=/tank/testfile of=/dev/null bs=512 

Und das Ergebnis:

              capacity     operations     bandwidth 
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank        1.50G  1.45G      0     57    921   102K
  raidz2    1.50G  1.45G      0     57    921   102K
    sda         -      -      0     18      0  34.1K
    sdb         -      -      0     18      0  34.1K
    sdc         -      -      0     19    921  34.1K
cache           -      -      -      -      -      -
  sdd        512M   497M    736      0  91.9M   1023
----------  -----  -----  -----  -----  -----  -----

Jetzt werden Daten von L2ARC gelesen, aber erst nach dem Umschalten der oben genannten Modulparameter.

Ich habe auch gelesen, dass L2ARC zu groß dimensioniert sein kann. Aber Threads, die ich zu diesem Thema gefunden habe, bezogen sich auf Leistungsprobleme oder darauf, dass die Speicherkarte für L2ARC L1ARC verdirbt. Die
Leistung ist hier nicht mein Problem, und soweit ich das beurteilen kann, ist die Speicherkarte für L2ARC auch nicht so groß.

[root@host ~]# grep hdr /proc/spl/kstat/zfs/arcstats 
hdr_size                        4    279712
l2_hdr_size                     4    319488

Wie bereits erwähnt, bin ich nicht sicher, ob dies das beabsichtigte Verhalten ist oder ob ich etwas übersehe.

Antwort1

Nachdem ich mich also hauptsächlich mit diesem Thema befasst habe,dieser Beitrag, dies scheint das Standardverhalten von ZFS zu sein.

Was passiert, ist, dass die Datei nach dem Lesen in L1ARC gelangt und aufgrund der zugegriffenen Blöcke davon ausgegangen wird, dass sie in L2ARC abgelegt ist.
Beim zweiten Lesen der Datei führt ZFS nun ein Prefetching der Datei durch, das L2ARC umgeht, obwohl die Blöcke der Datei in L2ARC gespeichert sind.

Wenn Sie das Prefetching mit vollständig deaktivieren zfs_prefetch_disable=1oder ZFS anweisen, das Prefetching auf L2ARC mit durchzuführen l2arc_noprefetch=0, werden beim Lesen die Blöcke der Datei verwendet, die sich in L2ARC befinden.
Dies kann erwünscht sein, wenn Ihr L2ARC im Vergleich zu den gelesenen Dateien groß genug ist.
Aber man möchte vielleicht nur metadatamit in L2ARC schreiben zfs set secondarycache=metadata tank. Dadurch wird verhindert, dass große Dateien in L2ARC landen und nie gelesen werden. Da diesverderbenL2ARC und könnte Blöcke kleinerer Dateien, die nicht vorab abgerufen werden, sowie Metadaten, die Sie in L2ARC behalten möchten, aussortieren.

Ich habe keine Möglichkeit gefunden, ZFS anzuweisen,nur kleine Dateienin L2ARC und nicht das Zusammenführen der Prefetch-Kandidaten in L2ARC. Daher muss man derzeit je nach Dateigröße und L2ARC-Größe einen Kompromiss eingehen.
Ein anderer Ansatz scheint in der ZoL 0.8.0-Version verfügbar zu sein, wo es möglich ist, verschiedeneZuordnungsklassenund sollte es ermöglichen, beispielsweise Ihre Metadaten auf schnellen SSDs zu speichern, während Datenblöcke auflangsamrotierende Scheiben. Damit bleibt der Streitkleine DateienVergleichegroße Dateienfür L2ARC, löst aber das Problem des schnellen Zugriffs auf Metadaten.

Antwort2

In diesem Fall versucht ZFS, die L2ARC-Bandbreite für zufällige/nicht gestreamte Lesevorgänge beizubehalten, da ein Angriff auf die physischen Festplatten die Leistung beeinträchtigen würde. Streaming-Lesevorgänge werden von mechanischen Festplatten recht gut unterstützt, und jeder Pool mit 6/8+ Festplatten wird wahrscheinlich jedes SATA-L2ARC-Gerät für sequentielle Lesevorgänge übertreffen. Und jeder mittelgroße Zpool (d. h. 24/48+ Festplatten) bieteteine Mengeder sequentiellen Realbandbreite.

Wie Sie festgestellt haben, können Sie L2ARC so ändern, dass es sich mehr wie ein Opfercache verhält (d. h. alles speichern, was aus ARC entfernt wurde; wenn ein Block auf L2ARC gefunden wird, nicht einmal versuchen, auf den Hauptpool zuzugreifen). Bei einigen bestimmten Setups kann dies eine gute Sache sein; ZFS wurde jedoch (korrekterweise) so konzipiert, dass die Abnutzung/Nutzung von L2ARC dort erhalten bleibt, wo sie wirklich von Vorteil sein kann: zum Zwischenspeichern wirklich verwendeter Blöcke für eine schnellere Leistung beim zufälligen Lesen.

verwandte Informationen