Kafka圧縮コーデックの比較: Zstd vs. Snappy vs. Gzip

KafkaのZstd、Snappy、Gzip圧縮をレイテンシ、CPUコスト、ネットワーク使用量、ストレージ、プロデューサー設定の観点から比較します。

Kafka圧縮コーデックの比較: Zstd vs. Snappy vs. Gzip

Kafkaの圧縮は、ボトルネックの位置を変えます。ネットワークとディスクのトラフィックが減り、プロデューサーとコンシューマーのCPU負荷が増加します。Kafkaは大量のデータ処理に優れていますが、パフォーマンスを最適化するには、いくつかの主要なパラメーターの調整が必要になることがよくあります。チューニングの最も重要な領域の1つは、特に高ボリュームまたはネットワークが制約された環境において、メッセージ圧縮です。

最適なKafka圧縮コーデックは、CPU、ネットワーク帯域幅、ブローカーディスク、コンシューマー容量のどれが不足しているかによって異なります。

Kafkaにおける圧縮の理解

Kafkaでは、プロデューサーがメッセージをブローカーに送信する前に圧縮できます。ブローカーは圧縮されたバッチを保存し、コンシューマーはデータを取得して解凍します。このプロセスにより、計算負荷がネットワーク/ディスク層からCPU層に移行します。コーデックの選択は、これらのリソース間のバランスを決定するため、非常に重要です。

Kafkaは一般的にnonegzipsnappylz4zstdをサポートしていますが、正確なサポートはブローカーとクライアントのバージョンに依存します。

圧縮の設定

圧縮は通常、compression.typeプロパティを使用してプロデューサー側で設定します。ブローカーはプロデューサーが使用するコーデックを読み取れる必要があります。

# プロデューサー設定の例
compression.type=zstd

Kafka圧縮コーデックの詳細

ここでは、一般的に使用される3つの主要なコーデック(Gzip、Snappy、Zstd)を、それぞれの典型的なパフォーマンスプロファイルに基づいて比較します。

1. Gzip (GNU Zip)

Gzipは、DEFLATEアルゴリズムに基づく、確立された汎用圧縮アルゴリズムです。多くの場合、強力な圧縮を提供しますが、Zstdはレベルとデータ形状によっては、多くのイベントペイロードでそれに匹敵するか、それを上回ることがあります。

  • 圧縮率: 高い(特にテキスト主体のペイロードの場合)。
  • CPU使用率: 高い(圧縮と解凍の両方にかなりのCPU時間を必要とする)。
  • レイテンシへの影響: CPU使用率が高いため、特に大きなバッチを圧縮する場合に顕著なレイテンシが発生する可能性がある。

最適な使用例: ストレージの節約とネットワーク帯域幅の節約が最優先で、CPUリソースが豊富にある場合、またはメッセージスループット要件が比較的低い場合。

2. Snappy

Googleによって開発されたSnappyは、最大限の圧縮ではなく、速度を重視して設計されています。GzipやZstdよりも結果のファイルサイズが大きくなる場合でも、非常に高速な圧縮と解凍速度を優先します。

  • 圧縮率: 中程度から低い。
  • CPU使用率: 低い(実行速度が非常に速い)。
  • レイテンシへの影響: 最小限。Snappyは、エンドツーエンドのレイテンシへの影響がほぼゼロであることで知られている。

最適な使用例: 低レイテンシが絶対的な最優先事項である高スループットシステム。計算上のボトルネックを最小限に抑えながら、ある程度のネットワーク節約効果も得られるため、多くのKafkaデプロイメントでデフォルトの選択肢となることがよくあります。

3. Zstandard (Zstd)

もともとFacebook(Meta)によって開発されたZstandardは、現代の競争相手です。Zstdは、選択された圧縮レベルに応じて、Snappyよりも優れたパフォーマンスを提供しながら、Gzipに近いかそれ以上の圧縮率を達成することを目指しています。

Zstdは調整可能な圧縮レベルをサポートしています。Kafkaクライアントは、これをサポートするクライアントのコーデック固有の設定を通じてこれを公開します。

  • レベル1(高速): 多くの場合、速度でSnappyを上回りながら、Snappyよりも優れた圧縮を提供します。

  • レベル3-5(バランス): 一般的なスイートスポットであり、低いCPUオーバーヘッドで良好な圧縮率を提供します。

  • レベル10+(高): Gzipの圧縮率に近づきますが、一般的に解凍速度は高速です。

  • 圧縮率: 可変(中程度から非常に高いまで)。

  • CPU使用率: 選択されたレベルによって大きく異なる(低い場合も高い場合もある)。

  • レイテンシへの影響: 一般的に低いレベルでは非常に低く、Snappyに匹敵する。

最適な使用例: ほぼすべての最新のKafkaデプロイメント。Zstdは、バランスを正確に調整する柔軟性を提供します。低レイテンシが必要な場合は、レベル1または3を使用します。ストレージの節約が必要な場合は、より高いレベル(例:9または11)を使用します。

比較分析:コーデックの選択

最適なコーデックは、特定のクラスターアーキテクチャのボトルネックに完全に依存します。

コーデック 圧縮率 圧縮速度 解凍速度 CPUオーバーヘッド 理想的なユースケース
Snappy 低い 非常に速い 非常に速い 最も低い レイテンシ重視、高スループット
Zstd (レベル1-3) 中程度 速い 非常に速い 非常に低い 最新、バランスの取れたパフォーマンス
Zstd (レベル5-11) 高い 中程度 速い 中程度 柔軟なストレージ/パフォーマンスのトレードオフ
Gzip 最も高い 遅い 遅い 最も高い ストレージアーカイブ、低スループット

実践的な決定ガイド

以下のガイドラインを使用して、要件をコーデックにマッピングします。

  1. レイテンシが重要な場合(例:リアルタイム金融フィード): SnappyまたはZstdレベル1を選択します。これらはCPU負荷が最も低くなります。
  2. ストレージコストが重要な場合(例:データを数か月間保持する場合): Gzipまたは高レベル(15以上)のZstdを選択します。より多くのCPUリソースを割り当てる準備をしてください。
  3. 汎用の高スループットシステムの場合: **Zstd(レベル3または5)**が圧倒的にお勧めです。速度をあまり犠牲にすることなく、Snappyよりも優れた効率(圧縮バイトあたりのCPUが少ない)を提供することがよくあります。

設定例:速度の最適化(Zstd)

Zstdを使用していて、Snappyに近いパフォーマンスとわずかに優れた圧縮を実現したい場合は、プロデューサー設定でレベルを明示的に設定します。

# Zstdを使用して速度を優先するプロデューサー設定
compression.type=zstd
compression.zstd.level=3

圧縮レベルに関する警告: Kafkaクライアントは、サポートされている場合、compression.zstd.levelcompression.gzip.levelなどのコーデック固有のレベル設定を公開します。Snappyは同じようにレベル調整できません。レベルを上げると、圧縮にかかる時間が大幅に増加し、これはバッチが送信されるに発生することに注意してください。

プロデューサーとコンシューマーのパフォーマンスに関する考慮事項

圧縮は接続の両側に影響を与えることを覚えておくことが重要です。

プロデューサーへの影響(圧縮時間)

プロデューサーは、レコードのバッチ全体が準備できるのを待ってから、それを圧縮して送信する必要があります。圧縮時間がlinger.msを超えると、プロデューサーはバッチを時期尚早に、または遅すぎるタイミングで送信する可能性があります。非常に遅い圧縮(高レベルのGzipなど)は、プロデューサーにより頻繁に小さなバッチを送信させる可能性があり、リクエストのオーバーヘッドが増加します。

コンシューマーへの影響(解凍時間)

コンシューマーは、データを処理する前に解凍するためにCPUサイクルを費やす必要があります。コンシューマーのCPUが最大限に使用されている場合、ネットワークスループットが十分であっても、解凍がボトルネックになり、コンシューマーラグが発生する可能性があります。解凍速度は圧縮速度よりも重要であることが多いです。なぜなら、それはコンシューマーのレイテンシに直接影響するからです。

このため、SnappyやZstd(解凍ルーチンが非常に高速)のようなコーデックは、解凍ルーチンが比較的遅いGzipよりも好まれます。

まとめ

新しいKafkaワークロードでは、低レベルまたは中程度のレベルのZstdから始め、実際のペイロードでベンチマークを実施してください。プロデューサーまたはコンシューマーのCPUが逼迫しており、レイテンシが最も重要な場合はSnappyを使用してください。互換性またはストレージ削減が追加のCPUコストを上回る場合にのみGzipを使用してください。