web-dev-qa-db-ja.com

Solaris11.3でのZFSL2ARCキャッシュのプライミング

Solaris11.3でZFSL2ARCキャッシュを準備する良い方法はありますか?

L2ARCは、ファイルから順番に読み取られたブロックを無視するように設計されています。これは進行中の操作には意味がありますが、初期のウォームアップまたはベンチマークのためにキャッシュを準備することは困難です。

さらに、高度に断片化されたファイルは、シーケンシャル読み取りがL2ARCにキャッシュされることで大きなメリットが得られます(ディスク上ではランダム読み取りであるため)が、現在のヒューリスティックでは、L2ARCが10%しか満たされていない場合でも、これらのファイルはキャッシュされません。

Solaris 10および11の以前のリリースでは、各ファイルでddを2回続けて使用することに成功しました。最初のddはファイルをARCに読み込み、2番目のddはバッファをくすぐったように見えたため、L2ARCキャッシングの対象になりました。同じ手法は、Solaris11.3では機能しないようです。

問題のファイルのレコードサイズが8kであることを確認しました。 zfs_prefetch_disableを設定しようとしましたが、これはL2ARCの動作に影響を与えませんでした 更新:zfs_prefetch_disableが重要であることが判明しました。以下の私の回答を参照してください。

それを行う良い方法がない場合は、ファイルの100%を超えるランダムな読み取りを生成するツールの使用を検討します。キャッシュが11.3で永続化されていることを考えると、これは時間の価値があるかもしれません。このようなツールはありますか?

5
Tom Shaw

少し実験して、4つの可能な解決策を見つけました。

それぞれのアプローチで、ステップを実行してから、さらにデータを読み取り続けてZFS ARCキャッシュをいっぱいにし、ARCからL2ARCへのフィードをトリガーする必要があります。データがすでにメモリにキャッシュされている場合、または各ブロックのディスクの圧縮サイズが32kBを超える場合、これらのメソッドは通常何も実行しないことに注意してください。

1。文書化されたカーネルフラグを設定しますzfs_prefetch_disable

L2ARCはデフォルトで、自動的にプリフェッチされたデータのキャッシュを拒否します。 ZFSプリフェッチ機能を無効にすることでこれを回避できます。とにかく、このフラグはデータベースワークロードに適していることがよくあります。

echo "zfs_prefetch_disable/W0t1" | mdb -kw

..または永続的に設定するには、/etc/systemに以下を追加します。

set zfs:zfs_prefetch_disable = 1

これで、ファイルがddを使用して読み取られた場合でも、L2ARCの対象になります。

運用上、この変更により、テストでの読み取りの動作も改善されます。通常、ZFSはシーケンシャル読み取りを検出すると、キャッシュから読み取るだけでなく、データvdevとキャッシュvdevの間でスループットのバランスを取りますが、キャッシュデバイスがデータデバイスよりも大幅に低レイテンシまたは高スループットである場合、パフォーマンスが低下します。

2。データを書き直します

データがZFSファイルシステムに書き込まれると、データはARCにキャッシュされ、(ブロックサイズの基準を満たしている場合)L2ARCにフィードする資格があります。データの書き換えは必ずしも簡単ではありませんが、一部のアプリケーションやデータベースではライブで書き換えることができます。アプリケーションレベルのファイルミラーリングまたはデータファイルの移動を介して。

問題:

  • アプリケーションによっては、常に可能とは限りません。
  • 使用中のスナップショットがある場合、余分なスペースを消費します。
  • (しかし、明るい面では、結果のファイルはデフラグされます。)

。文書化されていないカーネルフラグの設定を解除しますl2arc_noprefetch

これは、OpenSolarisソースコードの読み取りに基づいており、完全にサポートされていないことは間違いありません。自己責任。

  1. l2arc_noprefetchフラグを無効にします。

    echo "l2arc_noprefetch/W0" | mdb -kw
    

    このフラグが無効になっているときにARCに読み込まれたデータは、シーケンシャル読み取りであっても(ブロックがディスク上で最大32kである限り)、L2ARCの対象になります。

  2. ディスクからファイルを読み取ります。

    dd if=filename.bin of=/dev/null bs=1024k
    
  3. l2arc_noprefetchフラグを再度有効にします。

    echo "l2arc_noprefetch/W1" | mdb -kw
    

4。データをランダムに読み取る

(Perlハッシュの順序に基づいて)疑似ランダムに8kBチャンクのファイルを読み取るPerlスクリプトを作成しました。より大きなチャンクでも機能する可能性がありますが、まだテストしていません。

#!/usr/bin/Perl -W

my $BLOCK_SIZE = 8*2**10;
my $MAX_ERRS = 5;

foreach my $file (@ARGV) {
        print "Reading $file...\n";
        my $size;
        unless($size = (stat($file))[7]) {print STDERR "Unable to stat file $file.\n"; next; }
        unless(open(FILE, "<$file")) {print STDERR "Unable to open file $file.\n"; next; }
        my $buf;
        my %blocks;
        for(my $i=0;$i<$size/$BLOCK_SIZE;$i++) { $blocks{"$i"} = 0; }
        my $errs = 0;
        foreach my $block (keys %blocks) {
                unless(sysseek(FILE, $block*$BLOCK_SIZE, 0) && sysread(FILE, $buf, $BLOCK_SIZE)) {
                        print STDERR "Error reading $BLOCK_SIZE bytes from offset " . $block * $BLOCK_SIZE . "\n";
                        if(++$errs == $MAX_ERRS) { print STDERR "Giving up on this file.\n"; last; }
                        next;
                }
        }
        close(FILE);
}

問題:

  • これには時間がかかり、ディスクに重いワークロードがかかります。

残りの問題

  • 上記のメソッドは、L2ARCへのフィードに適格なデータをメインメモリに取得しますが、フィードをトリガーしません。 L2ARCへの書き込みをトリガーするために私が知っている唯一の方法は、データの読み取りを継続してARCに圧力をかけることです。
  • SRU1.3.9.4.0を搭載したSolaris11.3では、L2ARCが期待される量を完全に拡張することはめったにありません。 SSDデバイスに圧力がかかっていない場合でもevict_l2_eligible kstatが増加し、データがドロップされていることを示します。キャッシュされていないデータのこの残りの塊は、パフォーマンスに不均衡な影響を及ぼします。
3
Tom Shaw

実際のワークロードを使用し、arcstatで結果を監視することをお勧めします。

何かのようなもの:

arcstat.py -f "time,read,l2read,hit%,hits,miss%,miss,l2hit%,l2miss%,arcsz,c,l2size" 1

キャッシュを「プライミング」する必要はないと思います。使用しているワークロードがキャッシュに自然に読み込まれない場合、それは代表的なベンチマークワークロードではありません。

例外的なユースケースがあるかもしれません(データセットサイズ、ARCサイズ、ワーキングセットサイズは?)ですが、一般的に、L2ARCへの焦点は強調されすぎています。

0
ewwhite