今日は、Linux0.7.10で最新のZFSを使用してL2ARCでいくつかのテストを行いました。 L2ARCがデータでいっぱいになるのを見てきましたが、デフォルトのモジュール設定では、L2ARCキャッシュにあるデータは変更されません。代わりに、データはメインプールのvdevから読み取られます。私も0.7.9でこの振る舞いを見ましたが、それが期待される振る舞いであるかどうかはわかりません。
それが予想される動作であったとしても、読み取られないデータでL2ARCを台無しにするのは奇妙だと思います。
テストインストールはVMです。
私はいくつかの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から読む準備ができました(長い序文で申し訳ありませんが、それは重要だと思いました)。
そこで、dd if=/tank/testfile of=/dev/null bs=512
コマンドを再度実行すると、2番目の端末でzpool iostat -v 5
を監視していました。
驚いたことに、ファイルはL2ARCにありますが、ファイルはL2ARCではなく通常のvdevから読み取られました。これはファイルシステム内の唯一のファイルであり、テスト中に他のアクティビティはアクティブになりません。
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から提供されます。再びdd if=/tank/testfile of=/dev/null bs=512
を実行し、2番目の端末でzpool iostat -v 5
を監視して、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
そして結果:
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のサイズが大きすぎる可能性があることも読みました。しかし、そのトピックについて私が見つけたスレッドは、パフォーマンスの問題またはL1ARCを台無しにするL2ARCのスペースマップに言及していました。
ここではパフォーマンスは私の問題ではありません。私が知る限り、L2ARCのスペースマップもそれほど大きくありません。
[root@Host ~]# grep hdr /proc/spl/kstat/zfs/arcstats
hdr_size 4 279712
l2_hdr_size 4 319488
すでに述べたように、それが意図した動作なのか、それとも何かが足りないのかはわかりません。
したがって、このトピック、主に この投稿 を読んだ後、これがZFSのデフォルトの動作であるようです。
何が起こるかというと、ファイルは読み取られた後にL1ARCに送られ、アクセスされたブロックのためにL2ARCに入れられたと見なされます。
ファイルの2回目の読み取りで、ZFSはファイルのプリフェッチを実行します。これにより、ファイルのブロックはL2ARCに格納されますが、L2ARCはバイパスされます。
zfs_prefetch_disable=1
を使用してプリフェッチを完全に無効にするか、l2arc_noprefetch=0
を使用してL2ARCでプリフェッチを実行するようにZFSに指示することにより、読み取りはL2ARCにあるファイルのブロックを利用します。
これは、読み取り中のファイルサイズと比較してL2ARCが十分に大きい場合に必要になることがあります。
しかし、metadata
をzfs set secondarycache=metadata tank
でL2ARCに入れたいだけかもしれません。これにより、大きなファイルがL2ARCになり、読み取られなくなるのを防ぎます。これはL2ARCを台無しにするので、プリフェッチされていない小さなファイルのブロックと、L2ARCに保持したいメタデータを削除する可能性があります。
ZFSに小さなファイルのみをL2ARCに入れ、プリフェッチ候補をL2ARCにマージしないように指示する方法が見つかりませんでした。したがって、今のところ、ファイルサイズとL2ARCサイズに応じて、トレードオフを行う必要があります。
ZoL 0.8.0リリースでは、異なるアプローチが利用できるようです。ここでは、異なる割り当てクラスを使用でき、例えばすることが可能データブロックを低速回転ディスクに残したまま、メタデータを高速SSDに配置します。これでも、L2ARCの競合小さいファイルと大きいファイルが残ります、ただし、メタデータの問題に対する高速アクセスを解決します。
この場合に発生するのは、ZFSがランダム/非ストリーミング読み取り用にL2ARC帯域幅を維持しようとしていることです。この場合、物理ディスクにアクセスするとパフォーマンスが低下します。ストリーミング読み取りは、機械式HDDから非常に適切に提供され、6/8以上のディスクを備えたプールは、シーケンシャル読み取りのSATAL2ARCデバイスよりもパフォーマンスが優れている可能性があります。また、中規模のzpool(つまり、24/48以上のディスク)では、十分にのシーケンシャルな実帯域幅が得られます。
見つけたように、L2ARCを変更して、ビクティムキャッシュと同様に動作させることができます(つまり、ARCから削除されたものをすべて保存します。L2ARCでブロックが見つかった場合は、メインプールにアクセスしようとしないでください)。一部の特定の設定では、これは良いことです。ただし、ZFSは、L2ARCの摩耗/使用を維持するように(正しく)設計されており、実際に使用されるブロックをキャッシュして、ランダム読み取りのパフォーマンスを向上させることができます。