バースト的なシーケンシャル書き込みのための ZFS のチューニング

バースト的なシーケンシャル書き込みのための ZFS のチューニング

これは以下の続きです:大容量ストレージによる高速ネットワーク書き込み設定が大幅に変更されました。

raid-z2私には、6 台のドライブ (すべて Exos X18 CMR ドライブ) を備えた単一のプールがあります。fio手動テストを使用して、アレイが平均で約 800 MB/秒のシーケンシャル書き込みを維持できることがわかっています。これは問題なく、このアレイの期待パフォーマンスと一致しています。マシンは、32G ECC RAM、NVMe ブート/システム ドライブ、2x10Gbps イーサネット ポート (Intel x550-T2) を備えた Ryzen5 Pro 2400 GE (4C/8T、3.8 GHz ブースト) です。私は最新の Arch システムと zfs 2.1.2-1 を実行しています。

私の使用例は、大部分が大容量 (~30G) の書き込み 1 回、読み取り 1 回の圧縮ビデオのビデオ アーカイブです。 を無効にしatime、 を設定し、 をrecordsize=1M設定しました。データは実際には圧縮不可能であり、テストでは、インターネットで言われているのに反して を使用した場合のパフォーマンスが よりも悪く、設計上重複データは存在しないことが示されました。このプールは、Samba を介してネットワーク上で共有されます。ネットワークと Samba を調整して、Windows マシン上の NVMe NTFS から NVMe ext4 への転送が 1GB/秒に達するようにしました。つまり、9K ジャンボ フレームで 10 Gbps リンクを飽和させるのにかなり近い値です。compressios=offdedup=offcompression=lz4off

ここで問題にぶつかります。30G のビデオ アーカイブ全体を 1GB/秒で、raid-z2800 MB/秒のシーケンシャル書き込みしかサポートできないアレイに転送できるようにしたいのです。私の計画は、RAM ベースのダーティ ページを使用してスピルオーバーを吸収し、クライアント側で転送が「完了」した後にディスクにフラッシュすることです。必要なのは、転送完了後(1024-800)*30~=7G約 10 秒でディスクにフラッシュできる RAM 内のダーティ ページだけだと考えました。このことによるデータ整合性への影響は理解していますし、停電でファイルが失われたり不完全になったりしても、1 か月以内であればいつでもファイルを再度転送できるので、リスクは許容範囲です。

しかし、ZFS を期待どおりに動作させることができません.../etc/modprobe.d/zfs.conf次のようにファイルを編集しました:

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

適切なmkinitcpio -Pコマンドを実行して initramfs を更新し、再起動後に設定が適用されたことを確認しました。

# 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

つまり、最大ダーティ ページを 24G に設定しました。これは必要な 7G よりはるかに大きい値で、この 80% が使用されるまで書き込みを遅らせないようにします。私の理解では、プールは、クライアント (Samba) からの書き込みを遅延で押し戻し始める前に、19G を RAM に吸収できるはずです。

しかし、Windows クライアントからの書き込みでは、書き込み速度が約 1 GB/秒で約 16 秒経過すると書き込みパフォーマンスが急激に低下します (iostatディスクがデータをフラッシュするために懸命に動作していることが依然として示されています)。これは、ZFS の書き込みスロットリングのプッシュバック メカニズムであるとしか考えられません。ただし、これは意味がありません。少なくとも、16 秒間に何もフラッシュされなかったとしても、3 秒後には設定されていたはずです。さらに、最後にもう一度低下します。画像を参照してください: [ ここに画像の説明を入力してください][https://i.stack.imgur.com/Yd9WH.png]

zfs_dirty_data_sync_percentダーティ ページ バッファーがデフォルトよりもかなり大きいため、書き込みを早く開始するように を調整しようとしましたzfs_vdev_async_write_active_{min,max}_dirty_percent。また、大きなダーティ バッファーで書き込み速度を上げるために、アクティブ IO スケーリングを早めに開始するように調整しようとしました。どちらも崖の位置をわずかに移動しましたが、期待したものにはほど遠いものでした。

質問:

  1. 書き込みスロットル遅延の仕組みを誤解しているのでしょうか?
  2. 私がやろうとしていることは可能でしょうか?
  3. もしそうなら、私は何を間違っているのでしょうか?

はい、わかっています。文字通り数秒を追い求めているだけで、これを達成するために費やした労力は決して回収できません。それでも大丈夫です。現時点では、これは私と ZFS の間の個人的な問題であり、原則の問題です ;)

答え1

zfs_txg_timeoutまた、パラメータを現在のデフォルトの 5 秒から 7G/0.2G/s = 35 秒程度に増やす必要があるため、40 秒に設定すれば十分なはずです。

あなたの/etc/modprobe.d/zfs.conf

options zfs zfs_txg_timeout=40

ARC は、書き込みキャッシュにまったく関与しない「読み取り」キャッシュなので、30 GB の書き込みストリームごとにブロック書き込みキャッシュが吸収しなければならない 7 GB 以上の余分なデータを消費するように ARC が設定されていないことを確認してください。ZFS の書き込みキャッシュは、他の単純なブロック書き込みキャッシュ ( commitext4 ファイルシステムのパラメータなど) と同じなので、すべての転送シナリオで RAM が枯渇しないことを確認するために、必ず非本番環境でテストしてください。

答え2

zfs primarycache = all (デフォルト) の場合、書き込みごとに ARC が更新されます。現在書き込んでいるデータの読み取り待ち時間が重要でない場合は、zfs primarycache=meta を設定することをお勧めします。

答え3

現在、必要な RAM またはストレージ リソースが不足しています。

必要な I/O スループット レベルと最悪の場合のパフォーマンスを考慮して設計します。

記述されているデータの作業セットに対して、あらゆる条件下で 1GB/秒のスループットが必要な場合は、ディスク スピンドル数またはインターフェイス スループットがこれをサポートできることを確認してください。

関連情報