Kafkaブローカー設定ガイド:最大パフォーマンスを実現するために
ディスク、JVM、レプリケーション、スレッド、ソケットバッファ、リテンション、メッセージサイズの設定でKafkaブローカーのパフォーマンスをチューニングします。
Kafkaブローカー設定ガイド:最大パフォーマンスを実現するために
Kafkaは高スループットと耐障害性を実現するように設計されていますが、ブローカーのデフォルト設定はワークロードに合わせて調整する必要があります。間違ったディスク構成、ヒープサイズ、レプリケーション設定、スレッド数は、健全なクラスターをレイテンシ問題に変えてしまう可能性があります。
このガイドでは、Kafkaブローカーのパフォーマンス設定に焦点を当てます:ディスクI/O、JVMサイジング、レプリケーションの耐久性、リクエストスレッド、ソケットバッファ、メッセージ制限について説明します。
1. 高性能基盤の確立
特定のKafkaブローカー設定を調整する前に、ハードウェアとオペレーティングシステム層での最適化から始める必要があります。Kafkaは本質的にディスクI/Oとネットワークに依存しています。
ディスクI/O:重要な要素
Kafkaはシーケンシャル書き込みに依存しており、これは非常に高速です。しかし、不適切なディスク選択やファイルシステム設定は、パフォーマンスを著しく低下させる可能性があります。
| 設定/選択 | 推奨 | 根拠 |
|---|---|---|
| ストレージタイプ | 高速SSD(NVMe推奨) | コンシューマーのルックアップやインデックス操作において、優れたレイテンシとランダムアクセス性能を提供します。 |
| ディスク構成 | Kafkaログ専用ディスク | OSやアプリケーションのログとのリソース競合を回避します。JBOD(Just a Bunch Of Disks)を使用して複数のマウントポイントの並列I/O機能を活用し、ハードウェアRAIDではなくKafkaにレプリケーションを任せます。 |
| ファイルシステム | XFSまたはext4 | XFSは一般的に、大容量かつ高並列処理においてext4よりも優れたパフォーマンスを発揮します。 |
OSチューニングのヒント
Linuxでは、カーネルとストレージタイプに適したI/Oスケジューラを使用します。古いカーネルではSSDにdeadlineやnoopがよく使われていましたが、新しいカーネルではmq-deadline、none、kyberが一般的です。また、vm.swappinessを低く設定して、負荷がかかったときにブローカープロセスがスワップに追い出されないようにします。
JVMとメモリ割り当て
主要な設定はKafkaブローカーのヒープサイズです。ヒープが大きすぎるとGCポーズが長くなり、小さすぎるとGCサイクルが頻繁に発生します。
ベストプラクティス: Kafkaプロセスに5GBから8GBのヒープメモリを割り当てます(KAFKA_HEAP_OPTS)。残りのシステムRAMは、OSがページキャッシュとして使用できるように残しておきます。これは、最近のログセグメントを高速に読み取るために不可欠です。
# kafka-server-start.sh でのJVM設定例
export KAFKA_HEAP_OPTS="-Xmx6G -Xms6G -XX:+UseG1GC"
2. コアブローカー設定(server.properties)
これらの設定は、クラスター内でのデータの保存、レプリケーション、管理方法を決定します。
2.1 レプリケーションと耐久性
パフォーマンスは耐久性とバランスを取る必要があります。レプリケーションファクターを増やすと耐障害性は向上しますが、書き込みごとにネットワーク負荷が増加します。
| パラメータ | 説明 | 推奨値(例) |
|---|---|---|
default.replication.factor |
新しいトピックのデフォルトのレプリカ数。 | 3(標準的な本番環境値) |
min.insync.replicas |
プロデュースリクエストを成功と見なすために必要な、同期中のレプリカの最小数。 | 2(RF=3の場合、高い耐久性を保証) |
ヒント:
min.insync.replicasをdefault.replication.factorのN-1に設定します。プロデューサーがacks=allを使用する場合、この設定により、成功を確認する前に必要な数のレプリカにメッセージが書き込まれることが保証され、強力な耐久性が確保されます。
2.2 ログ管理とサイジング
Kafkaはトピックデータをセグメントに保存します。適切なセグメントサイジングにより、シーケンシャルI/Oが最適化され、クリーンアップが簡素化されます。
log.segment.bytes
この設定は、ログファイルセグメントが新しいファイルにロールオーバーするサイズを決定します。セグメントが小さいとファイル処理のオーバーヘッドが増加し、大きすぎるとクリーンアップとフェイルオーバーリカバリが複雑になります。
- 推奨値:
1073741824(1 GB)
log.retention.hours と log.retention.bytes
これらの設定は、古いデータが削除されるタイミングを制御します。パフォーマンス上の利点は、ブローカーが管理するデータの総サイズを最小限に抑えることから得られますが、リテンションはビジネス要件を満たす必要があります。
- 考慮事項: 主に時間ベースのリテンション(例:7日間)を使用する場合は、
log.retention.hours=168を設定します。バイトベースのリテンション(あまり一般的ではない)を使用する場合は、利用可能なディスク容量に基づいてlog.retention.bytesを設定します。
3. ネットワーク、スレッド、スループットの最適化
Kafkaは内部スレッドプールを使用して、ネットワークリクエストとディスクI/Oを管理します。これらのプールをチューニングすることで、ブローカーは同時クライアント接続を効果的に処理できます。
3.1 ブローカースレッド設定
num.network.threads
これらのスレッドは、受信クライアントリクエスト(ネットワーク多重化)を処理します。ソケットからリクエストを読み取り、I/Oスレッドによる処理のためにキューに入れます。ネットワーク使用率が高い場合は、この値を増やします。
- 初期値:
3または5 - チューニング: 同時接続数とネットワークスループットに基づいてスケールします。プロセッサコア数より高く設定しないでください。
num.io.threads
これらのスレッドは、実際のディスク操作(ログセグメントの読み取りまたは書き込み)とバックグラウンドタスクを実行します。このプールは、ディスクI/Oの待機に最も多くの時間を費やします。
- 初期値:
8または12 - チューニング: この値は、ブローカーがホストするデータディレクトリ(マウントポイント)とパーティションの数に応じてスケールする必要があります。より多くのパーティションが同時I/Oを要求する場合、より多くのI/Oスレッドが必要です。
3.2 ソケットバッファ設定
適切なサイズのソケットバッファは、特に高レイテンシ環境や非常に高いスループットが要求される環境でのネットワークボトルネックを防ぎます。
socket.send.buffer.bytes と socket.receive.buffer.bytes
これらはTCP送受信バッファサイズを定義します。バッファを大きくすると、ブローカーはパケットをドロップすることなく、より大きなデータバーストを処理できるようになります。これは高ボリュームのプロデューサーにとって重要です。
- デフォルト:
102400(100 KB) - 高スループットの推奨: これらを大幅に増やし、場合によっては
524288(512 KB)や1048576(1 MB)にします。
# ネットワークとスレッド設定
num.network.threads=5
num.io.threads=12
socket.send.buffer.bytes=524288
socket.receive.buffer.bytes=524288
socket.request.max.bytes=104857600
4. メッセージサイズとリクエスト制限
リソースの枯渇を防ぎ、ネットワーク負荷を管理するために、ブローカーはメッセージのサイズとリクエストの全体的な複雑さに制限を設けています。
4.1 メッセージサイズ制限
message.max.bytes
これは、ブローカーが受け入れる個々のメッセージの最大サイズ(バイト単位)です。クラスター全体で一貫している必要があり、プロデューサーの設定と一致している必要があります。
- デフォルト:
1048576(1 MB) - 警告: これを増やすと大きなペイロードが可能になりますが、メモリ消費、GCプレッシャー、コンシューマーのディスクI/Oレイテンシが大幅に増加します。厳密に必要な場合のみ増やしてください。
4.2 バックプレッシャーの処理
queued.max.requests
これは、ネットワークスレッドがそれ以上リクエストを読み取らなくなるまでに、キューに入れられたリクエストバッファで待機できるリクエストの最大数を定義します。これは、I/Oスレッドがネットワークスレッドに追いつかない場合にバックプレッシャーを適用します。
- チューニング: クライアントが頻繁に「Broker is busy」エラーを受信する場合、この値が低すぎる可能性があります。メモリへの影響を考慮して、慎重に増やしてください。
5. 主要なパフォーマンスパラメータのまとめ
| カテゴリ | パラメータ | パフォーマンスへの影響 | チューニング目標 |
|---|---|---|---|
| ディスク | log.segment.bytes |
シーケンシャルI/O効率、クリーンアップタイミング | 1 GB(I/Oバッチ処理の最適化) |
| 耐久性 | min.insync.replicas |
高い耐久性オーバーヘッド | RFのN-1に設定(復元力の確保) |
| スレッド | num.io.threads |
ディスク読み取り/書き込みの並行性 | パーティション/ディスクに応じてスケール(例:8-12) |
| ネットワーク | num.network.threads |
クライアント接続の並行性 | 同時クライアント数に応じてスケール(例:5) |
| ネットワーク | socket.send/receive.buffer.bytes |
負荷時のネットワークスループット | 高帯域幅/レイテンシのために増やす(例:512 KB) |
| 制限 | message.max.bytes |
メッセージペイロード処理、メモリプレッシャー | 可能な限り小さく保つ(デフォルトの1MBで通常十分) |
最終的なポイント
Kafkaブローカーのチューニングは、一度に1つのボトルネックを変更するのが最も効果的です。高速な専用ストレージ、十分なページキャッシュ、適切なレプリケーション設定、そしてnum.io.threads、num.network.threads、ソケットバッファへの測定された変更から始めてください。その後、実際のメッセージサイズ、プロデューサーレート、リテンションポリシー、レプリケーションファクターを使用してロードテストを行います。