私は専用サーバーで 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 から管理できるようにしておきたいのです。
私の質問:
128k (Proxmox のデフォルト) ではなく、すべてに対して小さい (16k) レコード サイズを使用し始めると、どのような不都合が生じますか?
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 top
SHA256TransformBlocks
したがって、推奨事項はすべてのケースに適しているとは限らず、元のセットに戻すこともできます。