Springbootは、カフカが繰り返し消費をリバランス統合しました

問題の説明

本番環境では、これらの日は、問題のカフカ繰り返し消費はログによって頻繁にリバランスアラームログを見つけることができます発見しました。

WARN  [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] o.a.k.c.c.i.ConsumerCoordinator - [Consumer clientId=consumer-1, groupId=boot_kafka] Synchronous auto-commit of offsets {am_performance_topic-0=OffsetAndMetadata{offset=27914, metadata=''}} failed: Commit cannot be completed since the group has already rebalanced and assigned the partitions to another member. This means that the time between subsequent calls to poll() was longer than the configured max.poll.interval.ms, which typically implies that the poll loop is spending too much time message processing. You can address this either by increasing the session timeout or by reducing the maximum size of batches returned in poll() with max.poll.records.
INFO  [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] o.a.k.c.c.i.ConsumerCoordinator - [Consumer clientId=consumer-1, groupId=boot_kafka] Revoking previously assigned partitions [am_performance_topic-0]
INFO  [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] o.s.k.l.KafkaMessageListenerContainer - partitions revoked: [am_performance_topic-0]
INFO  [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] o.a.k.c.c.i.AbstractCoordinator - [Consumer clientId=consumer-1, groupId=boot_kafka] (Re-)joining group
INFO  [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] o.a.k.c.c.i.AbstractCoordinator - [Consumer clientId=consumer-1, groupId=boot_kafka] Successfully joined group with generation 474
INFO  [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] o.a.k.c.c.i.ConsumerCoordinator - [Consumer clientId=consumer-1, groupId=boot_kafka] Setting newly assigned partitions [am_performance_topic-0]
INFO  [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] o.s.k.l.KafkaMessageListenerCont
复制代码

弱い鶏のために、私はこれだけカフカを知っている唯一の方法は、オンライン検索のすべての種類の中で最小です。ここで私はボーエンの問題を解決する上で助けに持っているものです。

カフカsession.timeout.ms heartbeat.interval.msパラメータならびにデータに関するいくつかの考えの差が記憶されている
カフカauto.offset.reset値詳細
auto.offset.resetの消費者パラメータカフカ
詳細春カフカプロデューサ-コンシューマ構成を
カフカについて話をしますコンシューマ・グループのコーディネーターとリバランスのメカニズム

分析

私たちは、アラームログを分析します:

グループがすでにリバランスし、他のメンバーにパーティションを割り当てているので、コミットを完了することはできません。この手段ポール(後続の呼び出しの間の時間)は、典型的にポーリングループがあまりにも多くの時間メッセージ処理を費やしていることを意味する、より長い構成max.poll.interval.msよりもありました。あなたはmax.poll.recordsで)セッションのタイムアウトを増やすことやpoll(に返されるバッチの最大サイズを減らすことによって、いずれかのこの問題に対処することができます。

あなたは、いくつかの重要なパラメータを取得することができmax.poll.interval.msmax.poll.records同様にsession timeoutこのログは、単純な翻訳であります

カフカグループが他のメンバーにリバランスし、パーティションされているので、提出を完了できません。これは通常、そのポーリングサイクルがmax.poll.interval.ms構成よりも長く、メッセージを処理するために時間がかかりすぎることを意味します。あなたは、セッションのタイムアウトを増やすか(ポーリングを減らすことによって)この問題を解決するために、最も大きなサイズ(max.poll.recordsを)返されたことができます

私たちは、に基づいて、これらのパラメータの意味を理解し始めカフカsession.timeout.ms heartbeat.interval.msパラメータの違いだけでなく、データ・ストレージ上のいくつかの考え
トピックとして、多くの場合、複数のパーティションを持っているが、我々はAになりますそのため、このトピックを費やすより多くの消費者を作成し、コンシューマ・グループ:個人消費、それにメッセージを仕切る:質問がありますか?コンシューマ・グループ、消費者、消費者グループ内のコンシューマ・グループ、および各グループコーディネーター:これは、3つの概念を含みます。conusmerパーティションは、管理プロトコルが実装されているグループによって割り当てられます。

グループコーディネーターJoinGroup要求に送信され、各消費者の消費者グループは、そこにそれが消費者としてリーダーの消費者を選択することですので、すべての消費者情報のこのグループコーディネーターのメンバーであり、リーダーの消費者に語ったと述べた:あなたは情報やメンバーを取ります私はあなたにそれを分割し、消費者の消費のために責任があるパーティション情報を配置するトピックをあげます

(パラメータpartition.assignment.strategyによって指定された)私達の構成によれば次に、リーダー消費者割当戦略は、それぞれのパーティションは、各消費者のために消費されるように計算します。したがって、各コンシューマ・グループ・コーディネータSyncGroupは、要求を送信するが、唯一の消費者は、パーティショングループコーディネータリーダー消費者の受信後、リーダーパーティション割り当てポリシーを要求し、この方式では消費者に配布しました。マップを描画し、これは以下の通りであります:

コンシューマ・グループのうち、消費者がリバランスをトリガする通常の状況においては、リバランスは、パーティションの概念を再定式化するために呼び出されます。そして、パーティションの良いアイデアを開発するには、速やかにパラメータとheartbeat.interval.msに関連する各消費者を、通知しなければなりません。具体的には、それは:リバランスが発生した場合、各消費者は、定期的に時間パラメータを指定heartbeat.interval.msグループコーディネータhearbeatに従って送信され、グループコーディネータは、各消費者の応答を含む各消費者の応答を受信しますグループコーディネーターは、個々の消費者の生存ことを知っていながらREBALANCE_IN_PROGRESSのアイデンティティは、その各消費者がすでに知っていること、リバランスを起こりました。

なぜheartbeat.interval.msとsession.timeout.msはそれを比較する必要がありますか?session.timeout.ms手段:グループコーディネーターの検出時間は、消費者のクラッシュが発生するために必要。コンシューマ・グループは、第二、消費者の内側にハングアップ検出session.timeout.msを取ります。例えばsession.timeout.ms = 10、heartbeat.interval.ms = 3

session.timeout.msがしきい値を指定し、「論理的」インデックス、ある---このしきい値コーディネーター内の10秒の任意のメッセージが受信されない場合、消費者、それが考慮され、消費者のコーディネーターがハングアップ。heartbeat.interval.msは、消費者にコーディネータにハートビートパケットを送信するために3秒ごとに、小さいheartbeat.interval.ms、やすいハートビートパケットを伝える「物理」の指標であり、それはTCP送信パケットの数に影響しますそしてそれは私が「物理的」指標の理由から、それを呼ばれる理由である、実質的な影響を持っていました。

期間heartbeat.interval.ms消費者グループ内のコーディネータがハートビートを受信しない場合、当社グループは、消費者の出す、それが正当化。消費者は、スティック上の小さなミスを犯したかのようにそれを殺しました。実際には、それはネットワークの遅延することが可能である、長い時間の消費者のGCが発生する可能性があり、それが影響し、ハートビートパケットが正常な状態に多分、次のハートビートに到着します。

heartbeat.interval.msは確かにコンシューマ・グループがリバランスを発生した場合、REBALANCE_IN_PROGRESS内部のハートビートパケットによって、消費者がタイムリーに知ることができるようになります以下session.timeout.msよりも、それによって消費者の消耗品のパーティションを更新し、リバランスを起こりました。session.timeout.ms以上の場合は、グループのコーディネーターは信じている消費者は、リバランスは、消費者に情報を伝えるない確かだと、ハングアップ。

それ以降のバージョンのkafka0.10.1では、session.timeout.msとmax.poll.interval.msが切り離さ。つまり:新しいKafkaConsumerはすなわち、Aカフカコンシューマ・インスタンスは、2つのスレッドが含まれている、二つのスレッドの後ろに実際に存在し、真ループプルメッセージconsumer.pollながら、このプロセスを実行するオブジェクトハートビートが、他のスレッドであります一つは、処理スレッドで、スレッドの呼び出しを処理するスレッドが実行メッセージ処理ロジックの方法として理解さconsumer.poll、およびハートビート・スレッドは、プログラマは、の「視界から隠される」バックグラウンドスレッドです。メッセージ処理ロジックが非常に複雑である場合、例えば、5分対処するために、次にmax.poll.interval.msは5分よりも大きな値に設定してもよいです。ハートビートスレッドが言及した上記に関連heartbeat.interval.msとパラメータで、すべてのハートビートスレッドheartbeat.interval.msは、彼がまだ生きていたことを証明するために、コーディネータにハートビートパケットを送信します。限り、ハートビートスレッドがsession.timeout.ms時間コーディネーター内にハートビートパケットを送信したとして、そのグループのコーディネーターは、現在のカフカの消費者が生きていると信じています。

kafka0.10.1前に、ハートビートパケットと、これら二つのプロセスのメッセージ処理ロジックは、一緒に結合され、これを考慮している送信します、長いメッセージが5分を処理する場合、およびsession.timeout.ms = 3000ms等カフカ消費者次いで処理されたメッセージを、一つのスレッドだけがハートビートパケットを送信する、グループ・コーディネーター・プロセスのハートビートパケットにメッセージを送信することはできませんので、消費者は、グループのうちの長いコーディネーター基を有する、より3000ms以上のグループのコンシューマ・グループ・コーディネーターアウトではありません。二つの別個の処理スレッドは、メッセージ処理ロジックを実行する責任があり、ハートビートスレッドはその後、ハートビートパケットを送信する責任がある:さえメッセージニーズ処理5分の場合、限り底スレッドがsession.timeout.msにハートビートパケットグループコーディネータにハートビートを送信するように、その消費者は、グループから削除されるのを恐れることなく、メッセージを処理し続けることができます。もう一つの利点:消費者が問題であるならば、我々はむしろ待ち時間よりmax.poll.interval.msが長い検出されるまで、session.timeout.msで検出することができます。

小概要

リバランスリピート消費を引き起こしたときに、2つの理由があります。

  • 一つはsession.timeout.ms時間に、ハートビートパケットは、ハートビートを送信しますheartbeat.interval.ms時間間隔あたりのスレッドのハートビートを受信しなかったです。
  • 他のmax.poll.interval.ms時間であり、消費者は時間max.poll.interval.msにオフセット更新返すために失敗したメッセージの数が処理されていないmax.poll.recordsを、這いカフカ情報。

第二ケースの上にある問題は非常に簡単です、この時間なので、解決策はmax.poll.records(メッセージ量のすべての投票を)、max.poll.interval.msタイムアウトを増やす減らすことです。あなたは春・カフカのフレームワークを使用している場合は、このセクションを作成する方法のパラメータはを参照してください春ブーツリファレンスガイドの上とボーエン詳細に春・カフカ生産者-消費者構成次のように最終改正しました:

kafka:
    producer:
      bootstrap-servers: 127.0.0.1:9092,127.0.0.1:9093,127.0.0.1:9094
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer:  org.apache.kafka.common.serialization.StringSerializer
    consumer:
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      enable-auto-commit: true
      group-id: boot_kafka
      auto-commit-interval: 100
      auto-offset-reset: earliest
      max-poll-records: 50
      bootstrap-servers:  127.0.0.1:9092,127.0.0.1:9093,127.0.0.1:9094
      properties:
        max.poll.interval.ms: 1200000
复制代码

max.poll.interval.msデフォルト値は300000(5分)で、max.poll.recordsデフォルト値は500です。より多くのパラメータおよび仕様のリファレンスApacheのカフカのドキュメント

繰り返し自動オフセットリセット何フィールド

説明を意味するauto.offset.reset値

  • 早い
    スタート支出オフセット提出から、地区の下に提出されたオフセットが、オフセットなし提出し、スクラッチ消費
  • 最新の
    データは、新しく作成したパーティションのオフセットのない、消費の際に提出され、そこには、地区の下に提出オフセットされたときに、最初から提出されたオフセット支出します
  • なし
    パーティションがある限り、例外がスローされ、存在しない提出オフセットとして、消費者の先頭からのオフセットの後にそこには、提出されたオフセットトピック地区

テストプロセス:

  • 早いモード:A1カフカソースの名前

    1. A1に、0001,0001は前に消費されることはありませんような話題がtest1の、のgroupIdで、データが(24)、事前に送られ、その後、(A1から選択*)SQL1を開始し、スクラッチ消費データからスタートする24を表示

    2. 図1は、(A1 SELECT * FROM)カフカ6、groupIdをA1、再起動SQL1のない置換を、SQL1が挙げ異なる送信データを停止し、最後の位置は、次に以降、消費者の消費、表示されます6記事データ

  • 最新モデル:A2のカフカソースの名前

    1. A2に、話題をb、groupIdをは0002,0002消費はありませんが、データがFLINKに関連する指標を参照、JMeterの上で結果を見ていない、(A2から選択*)SQL2を開始し、その後、事前に送られ、データが読み込まれません8つのデータは、(8)データのグループを送信のSQL2を殺すことなくバックだけ消費を送っ;.

    2. 図7(b)にデータを送信し、A2のgroupIdを交換することなく、1 SQL2で停止し、SQL2開始、7ショー後にのみデータを送信

  • なしモード:A3の名前カフカソース

    1. A3では、トピックはC、0001(非消費者)へのgroupIdセット、データが事前に送られるが、その後、SQL3(A3から選択*)、SQLが失敗し、ログにエラーを開始します。

    2. A3において、トピックは、C、0002までのGroupIDセット(消費が終わった)、出発SQL3(A3 SELECT * FROM)で、データを送信する、図8(c)に、ディスプレイ8のJMeterデータ。

おすすめ

転載: juejin.im/post/5e67cd2d518825492a721594