今日、Linux 0.7.10 の最新の ZFS を使用して L2ARC のテストをいくつか行いました。L2ARC がデータでいっぱいになることは確認しましたが、デフォルトのモジュール設定では、L2ARC キャッシュにあるデータは変更されません。代わりに、データはメイン プールの vdev から読み取られます。0.7.9 でもこの動作を確認しましたが、これが想定される動作かどうかはわかりません。
想定される動作だとしても、読み取られないデータで L2ARC を台無しにするのは奇妙だと思います。
テスト インストールは VM です。
- 最新パッチを適用した CentOS 7.5
- Linux 0.7.10 上の ZFS
- 2GBのRAM
ZFS 設定をいくつか行いました:
l2arc_headroom=1024
l2arc_headroom=1024
L2ARC人口の増加を加速させる
プールの作成方法とレイアウトは次のとおりです。実際の設定としては奇妙であることは承知していますが、これは L2ARC テスト専用です。
[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%
ここで、いくつかのデータをファイルに書き込み、デバイスの使用状況を確認します。
[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%
はい、一部のデータはすでに L2ARC に移動されていますが、すべてではありません。そのため、データをさらに何度か読み込んで、完全に L2ARC に移行します。
[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%
さて、L2ARC が設定され、読み取り準備が整いました。ただし、まず L1ARC を削除する必要があります。次の操作を実行しましたが、うまくいったようです。
[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
さて、これで L2ARC から読み取る準備ができました (前置きが長くてすみませんが、重要だと思ったので)。
そこで、コマンドを再度実行して、 2 番目のターミナルでdd if=/tank/testfile of=/dev/null bs=512
確認しました。zpool iostat -v 5
驚いたことに、ファイルは L2ARC にあるにもかかわらず、L2ARC ではなく通常の vdevs から読み取られました。これはファイルシステム内の唯一のファイルであり、テスト中に他のアクティビティはアクティブになっていません。
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_sz
その後、、、、zfetch_max_distance
などzfetch_max_streams
の設定をいじってl2arc_write_boost
、l2arc_write_max
奇数に設定してみました。しかし、何も変わりませんでした。
変更後
l2arc_noprefetch=0
(デフォルトは1
)- または
zfs_prefetch_disable=1
(デフォルトは0
) - 両方をデフォルトから切り替える
読み取りは L2ARC から提供されます。2番目のターミナルで再度実行しdd if=/tank/testfile of=/dev/null bs=512
て監視し、L1ARC を削除します。zpool iostat -v 5
[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
そして結果は次の通りです。
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
---------- ----- ----- ----- ----- ----- -----
現在、データは L2ARC から読み取られますが、上記のモジュール パラメータを切り替えた後にのみ読み取られます。
また、L2ARC のサイズが大きすぎる場合があることも読みました。しかし、そのトピックについて私が見つけたスレッドは、パフォーマンスの問題、または L2ARC のスペース マップが L1ARC を台無しにしていることについて言及していました。
パフォーマンスはここでの問題ではありませんし、私が知る限り、L2ARC のスペース マップもそれほど大きくはありません。
[root@host ~]# grep hdr /proc/spl/kstat/zfs/arcstats
hdr_size 4 279712
l2_hdr_size 4 319488
すでに述べたように、それが意図された動作なのか、それとも私が何かを見逃しているのかはわかりません。
答え1
このトピックについて読んだ後、主にこの郵便受けどうやらこれが ZFS のデフォルトの動作のようです。
ファイルは読み取られた後に L1ARC に移動し、ブロックがアクセスされたために L2ARC に配置されると見なされます。
次に、ファイルの 2 回目の読み取り時に、ZFS はファイルのプリフェッチを実行し、ファイルのブロックが L2ARC に格納されているにもかかわらず、L2ARC をバイパスします。
でプリフェッチを完全に無効にするかzfs_prefetch_disable=1
、 で ZFS に L2ARC でプリフェッチを行うように指示するとl2arc_noprefetch=0
、読み取りでは L2ARC にあるファイルのブロックが使用されます。
これは、読み取り中のファイル サイズに比べて L2ARC が十分に大きい場合に望ましい場合があります。ただし、でのみ L2ARC に
配置することをお勧めします。これにより、大きなファイルが L2ARC に残って読み取られなくなるのを防ぐことができます。これは、metadata
zfs set secondarycache=metadata tank
甘やかすL2ARC では、プリフェッチされていない小さなファイルのブロックや、L2ARC に保持したいメタデータが削除される可能性があります。
ZFSに指示する方法が見つからない小さなファイルのみL2ARCにプリフェッチ候補をマージしない。そのため、今のところは、ファイルサイズとL2ARCサイズに応じてトレードオフを行う必要がある。ZoL
0.8.0リリースでは、異なるアプローチが利用可能であるようで、異なる割り当てクラス例えば、メタデータを高速SSDに置き、データブロックをSSD上に残すといったことが可能になる。遅い回転ディスク。それでも競合は残る小さなファイル対大きなファイルL2ARC 用ですが、メタデータの高速アクセスの問題を解決します。
答え2
この場合、ZFSはランダム/非ストリーミング読み取り用にL2ARC帯域幅を確保しようとします。物理ディスクにアクセスするとパフォーマンスに大きな影響が出ます。ストリーミング読み取りは機械式HDDで十分に処理され、6/8以上のディスクを持つプールは、おそらくシーケンシャル読み取りのSATA L2ARCデバイスよりもパフォーマンスが優れています。また、中規模のzpool(つまり、24/48以上のディスク)は、多くの連続実帯域幅。
ご存知のとおり、L2ARC を変更して、被害者キャッシュに似た動作をさせることができます (つまり、ARC から追い出されたものはすべて保存し、L2ARC でブロックが見つかった場合は、メイン プールにアクセスしようとさえしません)。特定の設定では、これは良いことですが、ZFS は (正しく) L2ARC の消耗/使用を、実際に有利になる場所、つまり実際に使用されたブロックをキャッシュしてランダム読み取りのパフォーマンスを高速化できる場所のために保持するように設計されました。