ZFS レコードサイズを 128k ではなく 16k にすることのデメリット

ZFS レコードサイズを 128k ではなく 16k にすることのデメリット

私は専用サーバーで Proxmox を使用しています。本番環境ではまだ ext4 を使用していますが、ZFS を試してみることにしました。

そこで、異なるレコードサイズを持つ 2 つの別々の ZFS ストレージ プールを作成しました。

  • MySQL/InnoDB 以外のすべてで 128k
  • MySQL/InnoDB の場合は 16k (16k は私が使用しているデフォルトの InnoDB ページ サイズであるため)

16kプールを追加して、MySQL/InnoDBデータベースのパフォーマンスに本当に違いがあるかどうかを確認しました。本当に違いがあります。1秒あたりのトランザクションが約40%増加し、レイテンシが25%減少しました(これを徹底的にテストしました)。システムベンチそしてtpcc)。

現時点では実用的な理由から、2 つの別々の部分 (16k と 128k) ではなく、16k レコード サイズの 1 つの大きなプールを使用することを好みます。単一の ZFS プールにサブボリュームを作成し、それぞれに異なるレコード サイズを割り当てることができることはわかっていますが、これも避けたいことです。私はこれを Proxmox GUI から管理できるようにしておきたいのです。


私の質問:

  1. 128k (Proxmox のデフォルト) ではなく、すべてに対して小さい (16k) レコード サイズを使用し始めると、どのような不都合が生じますか?

  2. QEMU ディスク イメージには innodb_page_size に相当するものはありますか? ある場合、そのサイズはどれくらいですか?

    以下で確認してみましたqemu-img info:

     $ qemu-img info vm-100-disk-0.raw
     image: vm-100-disk-0.raw
     file format: raw
     virtual size: 4 GiB (4294967296 bytes)
     disk size: 672 MiB
    

サーバーの使用状況は次のとおりです。

  • www/php 用のコンテナ (多数の小さなファイルがありますが、コンテナ ディスク ファイル内にあります)
  • Java/Spring アプリケーション用のコンテナ (大量のログを生成します)
  • mysql/innodb データベースのコンテナ (説明は不要)
  • バックアップの圧縮を含むローカルバックアップ/復元操作
  • 大きな gzip ファイルをいじる (毎日ではない、優先度は低い)

答え1

短い答え:それは、想定される使用例によって異なります。一般的なルールとして、機械式ディスク (アクセス待ち時間はシーク時間 + 回転遅延によって左右される) では、デフォルトの 128K レコード サイズが適切な選択です。すべて SSD のプールの場合は、おそらく 16K または最大 32K を使用します (後者の方がデータの圧縮効率が大幅に向上する場合のみ)。

長い答え:HDDプールでは、データセットのレコードサイズはデフォルトの128Kのままにし、zvolのブロックサイズも128Kにすることをお勧めします。その理由は、7.2K RPM HDDのアクセスレイテンシはシークタイムに大きく左右されるからです。ないレコードサイズ/ボリュームブロックサイズに応じてスケールします。計算してみましょう。7.2K HDD の平均シーク時間は 8.3 ミリ秒ですが、128K ブロックの読み取りには約 1 ミリ秒しかかかりません。したがって、小さな 16K ブロックを読み取るためにヘッド シーク (8 ミリ秒以上の遅延) をコマンドすることは、特に小さな読み取り/書き込みでは r/m/w レイテンシによって影響を受けることを考慮すると、無駄に思えます。さらに、レコードサイズが小さいということは、メタデータのオーバーヘッドが大きくなり、圧縮が悪くなることを意味します。したがって、InnoDB は 16K IO を発行し、専用のデータセットの場合は 16K レコードサイズを使用して r/m/w と書き込み増幅を回避できますが、混合使用データセット (つまり、DB 自体だけでなく、より一般的なワークロードにも使用するデータセット) の場合は、特に小さなレコードサイズによる圧縮の影響を考慮すると、128K のままにすることをお勧めします。

しかし、SSDプールの場合は、16〜32Kの範囲で、はるかに小さいvolblocksize/recordsizeを使用します。その理由は、SSDはアクセス時間がはるかに短いが耐久性が限られているため、小さな書き込みのために128Kブロック全体を書き込むのは過剰に思えるからです。さらに、大きなレコードサイズによって要求されるIO帯域幅の増幅は、現代のSSDのような高IOPデバイスでははるかに懸念されます(つまり、帯域幅が飽和するリスクがあります)。前にIOP 制限に達しました)。

答え2

チューニングをお勧めしますもしも問題が発生します。

ZFS のデフォルトのレコード サイズは 128K であり、これはほとんどの構成とアプリケーションで許容され、有効です。

これには例外が含まれます:

  • 特定のデータベース アプリケーションでは、より小さい値が適切な場合があります。
    ただし、その代償として、圧縮の効果は大幅に低下し、トランザクション数の増加よりもパフォーマンスへの影響が大きくなる可能性があります。
  • 大規模なメディアワークロード(ビデオ編集など); 値が大きいほど便利です
  • 通常の ZFS 使用例の範囲外の特定のワークロード

データベースベンチマークのパフォーマンスが特定のレコードサイズで向上すると感じた場合は、それを使用してください。
ただし、現実的なサイズでテストしましたか?非ベンチマーク適切な調整を行っているかどうかを確認するために、作業負荷を調整しますか?

答え3

ちなみに、zfs のドキュメント自体によれば、「recordsize=16K」を設定することが推奨されています。

https://openzfs.github.io/openzfs-docs/パフォーマンスとチューニング/ワークロードチューニング.html#innodb

編集: かなり大きなデータベース (60GB を超えるデータ) を持つ仮想サーバーの Proxmox サーバーで 12 時間未満変更した後、この設定を元に戻しました。サーバーはデータの分析で大幅に遅れました。実際、'z_rd_int_'プロセスはそれぞれCPU使用率が低い状態から5%程度にまで上昇し、'z_wr_int_' 処理された CPU 使用率が低下しました。処理されたデータが少なくなったためと考えられます。

ただし、ハッシュ アルゴリズムを edonr() に変更すると、トップ カーネル関数として表示されなくなるzfs set checksum=edonr vmpoolというプラスの影響がありました。perf topSHA256TransformBlocks

したがって、推奨事項はすべてのケースに適しているとは限らず、元のセットに戻すこともできます。

関連情報