スケーラビリティとスループットのためのKafkaパーティションの最適化

パーティション最適化をマスターして、Kafkaトピックのピークパフォーマンスを解き放ちましょう。このガイドでは、理想的なパーティション数の決定、プロデューサー/コンシューバースループットのバランス調整、スケーラビリティの確保、よくある落とし穴の回避に不可欠な戦略を網羅しています。高スループット、低遅延のイベントストリーミングのためにパーティションを効果的に設定する方法を学びましょう。

42 ビュー

スケーラビリティとスループットのためのKafkaパーティションの最適化

Kafkaの分散的な性質とパーティションへの依存は、高スループットで耐障害性の高いイベントストリーミングを処理する能力の基盤です。トピックに割り当てられたパーティション数は、そのスケーラビリティ、パフォーマンス、およびコンシューマーの効率に直接影響します。最適なパーティション数を選択することは、画一的な決定ではなく、特定のユースケース、予想されるデータ量、および消費パターンを慎重に考慮する必要があります。この記事では、スケーラビリティを最大化し、イベントストリームで高スループットを実現するために、適切なKafkaパーティション数を決定するためのベストプラクティスを解説します。

Kafkaパーティションの理解

基本的に、Kafkaトピックは1つ以上のパーティションに分割されます。各パーティションは、順序付けられた不変のレコードのシーケンスであり、継続的にレコードが追記されます。パーティションはKafkaにおける並列性の単位です。これは以下のことを意味します:

  • プロデューサーはパーティションに書き込む: プロデューサーは、メッセージを送信するパーティションを選択できます(例:キーに基づく、またはラウンドロビン方式)。
  • コンシューマーはパーティションから読み取る: コンシューマーグループ内の各コンシューマーは、排他的に読み取る1つ以上のパーティションが割り当てられます。これにより、パーティション内のメッセージは、そのグループ内の単一のコンシューマーインスタンスによって順序通りに処理されることが保証されます。
  • ブローカーはパーティションをホストする: Kafkaブローカーはパーティションを保存します。多数のパーティションを持つトピックは、複数のブローカーに分散でき、ストレージと処理の水平スケーリングを可能にします。

パーティションの主な特性:

  • パーティション内での順序保証: 単一のパーティション内のメッセージは常に順序付けられています。グループ内のコンシューマーはこの順序を維持します。
  • パーティションを跨ぐ非順序性: 同じトピックの異なるパーティション間では、メッセージの順序は保証されません。
  • 並列性: パーティションの数は、プロデューサーとコンシューマーの両方にとって最大の並列性を決定します。トピックから並列に消費するコンシューマーの数は、パーティションの数以下である必要があります。

パーティション数に影響を与える要因

Kafkaトピックのパーティション数を決定する際には、いくつかの重要な要因を評価する必要があります:

1. スループット要件(プロデューサーとコンシューマー)

  • プロデューサースループット: プロデューサーが高いレートでメッセージを生成できる場合、利用可能なブローカー全体にこの負荷を分散し、プロデューサーインスタンスの潜在的なスケーリングを可能にするのに十分なパーティションが必要です。パーティションが多いほど、集約書き込みスループットが高くなる可能性があります。
  • コンシューマースループット: コンシューマーの合計スループットは、読み取ることができるパーティションの数によって制限されます。N個のパーティションがある場合、単一のコンシューマーグループでメッセージを並列処理できるコンシューマーは最大N個です。消費をより高速にする必要がある場合は、コンシューマーインスタンスをスケールアウトするために、より多くのパーティションが必要になります。

2. スケーラビリティの目標

  • 将来の成長: パーティションを減らすよりもトピックにパーティションを追加する方が簡単な場合が多いです(ただし、パーティションの増加にも影響があります)。時間の経過に伴う予想されるデータ量の増加と処理ニーズを考慮してください。
  • リバランス: 既存のトピックにパーティションを追加すると、コンシューマーグループに対してパーティションのリバランスがトリガーされます。これはKafka操作の正常な一部ですが、パーティションの過剰な追加による頻繁なリバランスは可用性に影響を与える可能性があります。通常、妥当な初期パーティション数を設定し、必要な場合にのみ増加させることが推奨されます。

3. ブローカーリソース

  • ディスク容量: 各パーティションは、それをホストするブローカー上でディスク容量を消費します。パーティションが多いほど、リーダー/フォロワーのレプリカのためのオーバーヘッドが増加し、ディスクI/Oが高くなる可能性があります。
  • ネットワーク帯域幅: パーティションには、プロデューサー、ブローカー、コンシューマー間のデータ転送が伴います。多数のパーティションは、ネットワークトラフィックと管理オーバーヘッドを増加させる可能性があります。
  • CPUとメモリ: 各パーティションは、リーダーシップの管理、レプリケーション、およびリクエストの処理のためにブローカーリソースを必要とします。パーティションが多すぎると、ブローカーリソースが過負荷になる可能性があります。

4. メッセージ順序要件

  • キーに基づく順序付け: メッセージの順序付けが重要であり、メッセージキーを使用している場合、同じキーを持つすべてのメッセージは同じパーティションに送られます。このシナリオでは、パーティションの数は、同じキーを持つメッセージを処理するために望ましい並列性と一致する必要があります。ホットキーがある場合、それは常に同じパーティションに送られ、その並列処理の可能性は、そのパーティションに割り当てられたコンシューマーに限定されます。
  • 厳密な順序付けが不要な場合: 厳密なメッセージ順序付けが要件でない場合は、スループットと並列性を優先して、メッセージをパーティション全体に自由に分散できます。

5. コンシューマーグループのスケーラビリティ

前述のように、パーティションの数は、コンシューマーグループ内でトピックから同時に読み取ることができるコンシューマーの最大数を決定します。より多くのコンシューマーインスタンスを追加して消費をスケールする必要がある場合は、必要なコンシューマーインスタンスの数以上のパーティションが必要です。

パーティション数を決定するための戦略

最適なパーティション数に到達するために役立つ実践的な戦略を以下に示します:

1. ベースラインから開始し、監視する

一般的な出発点として、最初に必要と予想されるコンシューマーインスタンスの数に、成長のためのバッファを加えてパーティション数を設定します。

  • 例: トピックに対して4つのコンシューマーインスタンスを実行する予定がある場合、6〜10のパーティションから開始します。これにより、すぐにパーティションを増やす必要なしに、さらにコンシューマーインスタンスを追加でき、書き込みの並列性も提供されます。

Kafkaクラスターとコンシューマーラグを継続的に監視してください。コンシューマーインスタンスを追加しても解決できない高いコンシューマーラグ(パーティション制限に達しているため)を観察した場合、それはパーティション数を増やす必要があることを明確に示しています。

2. 予想されるスループットに基づいて計算する

予想されるピークスループットと、単一のコンシューマーインスタンスのスループット能力を考慮して、必要なパーティション数を推定できます。

  • 計算式: Number of Partitions = (Total Expected Throughput / Throughput per Consumer Instance) * Buffer

    • 予想される合計スループット: トピックが処理する必要がある1秒あたりの最大メッセージ数(例:100,000メッセージ/秒)。
    • コンシューマーインスタンスあたりのスループット: 単一のコンシューマーインスタンスが処理できる1秒あたりの最大メッセージ数。これは、特定のアプリケーションとインフラストラクチャに合わせて測定し、理解する必要があります。
    • バッファ: スパイク、将来の成長、およびすぐに制限に達することを避けるための乗数(例:1.5倍から2倍)。
  • 例:

    • 予想されるピークスループット: 50,000 messages/sec
    • 単一コンシューマーインスタンスのスループット: 5,000 messages/sec
    • バッファ: 1.5x
    • Number of Partitions = (50,000 / 5,000) * 1.5 = 10 * 1.5 = 15

この場合、16のパーティションから開始するかもしれません。

3. ブローカーの能力と制限を考慮する

Kafkaクラスターが効果的に処理できるパーティションの総数に留意してください。厳密な上限はありませんが、ブローカーあたりのパーティション数が増加すると、パフォーマンスは低下します。一般的な推奨事項として、ブローカーあたり100〜200パーティション以下を目指すことですが、これはブローカーのハードウェアとワークロードによって大きく異なる可能性があります。

  • 総パーティション数: 5つのブローカーがあり、ブローカーあたりのパーティションを100未満に抑えたい場合、すべてのトピックの総パーティション数は理想的には500未満である必要があります。

4. キーの分散とホットパーティション

メッセージキーを使用する場合は、キーの分布を分析してください。少数のキーが圧倒的に優勢な場合、それらはすべて同じパーティションに送られ、「ホットパーティション」を作成します。これは、プロデューサー(パーティションをホストするブローカーが過負荷になる場合)とコンシューマー(そのパーティションに割り当てられた単一のコンシューマーインスタンスが追いつかない場合)の両方にとってボトルネックになる可能性があります。

  • 解決策: ホットパーティションが予想される場合は、次のような戦略を検討してください。
    • 複合キーを使用するか、キーをハッシュ化して負荷をより均等に分散する。
    • パーティションを増やして一般的なキーでも分散させ、より高いコンシューマー並列性を可能にする。

パーティションを持つトピックの作成と変更

新しいトピックを作成するときは、パーティション数を指定します。

特定の数のパーティションを持つトピックの作成

kafka-topics.shスクリプトを使用します。

kafka-topics.sh --create --topic my-high-throughput-topic \n  --bootstrap-server kafka-broker-1:9092,kafka-broker-2:9092 \n  --partitions 16 \n  --replication-factor 3
  • --partitions 16: トピックのパーティション数を16に設定します。
  • --replication-factor 3: 各パーティションは、耐障害性のために異なるブローカー間で3つのレプリカを持つことになります。

既存のトピックのパーティションの増加

これは一般的な操作ですが、影響があります。パーティション数は増やすことしかできず、減らすことはできません。

kafka-topics.shスクリプトを使用します。

kafka-topics.sh --alter --topic my-high-throughput-topic \n  --bootstrap-server kafka-broker-1:9092 \n  --partitions 24
  • --partitions 24: my-high-throughput-topicのパーティション数を24に増やします。

パーティションを変更する際の重要な考慮事項:

  • コンシューマーリバランス: パーティションを増やすと、そのトピックをサブスクライブしているすべてのコンシューマーグループに対してコンシューマーリバランスがトリガーされます。これにより、一時的に消費が停止する可能性があります。
  • 新しいパーティション: 新しいパーティションがトピックに追加されます。既存のメッセージは再パーティション化されません。
  • ブローカーリソース: ブローカーがパーティション数の増加を処理するのに十分な容量を持っていることを確認してください。

ベストプラクティスと落とし穴

実行すべきこと(Do):

  • 保守的に開始し、監視する: 妥当な数から開始し、観測されたメトリクス(コンシューマーラグ、スループット)に基づいて必要に応じてスケールアップします。
  • コンシューマーの並列性と合わせる: コンシューマーインスタンスを効果的にスケールアウトするのに十分なパーティションがあることを確認します。
  • 将来の成長を考慮する: 予想されるデータ量の増加と処理ニーズを考慮に入れます。
  • キーの分散を理解する: キーを使用する場合は、ホットパーティションを避けるためにその分布を分析します。
  • Kafka監視ツールを活用する: ツールを使用して、トピック/パーティションのメトリクス、コンシューマーラグ、およびブローカーの負荷を追跡します。

避けるべきこと(Don't):

  • パーティションを過剰にする(Over-partition): パーティションが多すぎると、オーバーヘッドが増加し、リバランスが遅くなり、ブローカーリソースが枯渇する可能性があります。
  • パーティションを少なくしすぎる(Under-partition): スケーラビリティとスループットが制限され、コンシューマーラグにつながります。
  • 任意の数値を盲目的に追う: 特定のユースケースと予想される負荷に基づいてパーティション数を決定します。
  • ブローカーの容量を忘れる: ブローカーがすべてのトピックの総パーティション数を処理できることを確認します。
  • パーティション間での完全な順序を期待する: 順序はパーティション内でのみ保証されることを覚えておいてください。

結論

Kafkaパーティションの最適化は、スケーラブルで高スループットのイベントストリーミングアーキテクチャを構築する上で重要なステップです。スループット要件、スケーラビリティの目標、コンシューマーの並列性、およびブローカーのリソースを慎重に考慮することで、各トピックの最適なパーティション数について十分な情報に基づいた決定を下すことができます。パーティション数は静的なものではなく、アプリケーションの進化に応じて調整が必要になる可能性がある構成であることを忘れないでください。継続的な監視とキャパシティプランニングへの積極的なアプローチにより、Kafkaトピックのパフォーマンスとスケーラビリティが維持されます。