04-カフカの設計原理の詳細な説明

Kafkaコアマスターコントローラーコントローラー

Kafkaクラスターには1つ以上のブローカーがあり、そのうちの1つがコントローラー(Kafkaコントローラー)として選出されます。コントローラーは、クラスター全体のすべてのパーティションとレプリカの状態を管理します。

  • パーティションのリーダーコピーに障害が発生した場合、コントローラーはパーティションの新しいリーダーコピーを選択する責任があります。
  • 特定のパーティションのISRセットの変更が検出されると、コントローラーはすべてのブローカーにメタデータ情報を更新するように通知する責任があります。
  • kafka-topics.shスクリプトを使用してトピックのパーティション数を増やす場合、コントローラーは新しいパーティションに他のノードを認識させる役割も果たします。

コントローラーの選出メカニズム

kafkaクラスターが開始されると、クラスター全体を管理するコントローラーとしてブローカーが自動的に選出されます。選出プロセスでは、クラスター内の各ブローカーがzookeeperに/ controller一時ノードを作成しようとし、zookeeperが確実にそこに配置します。は1つのブローカーのみです。正常に作成できる場合、このブローカーはクラスターのマスターコントローラーになります。

 コントローラーロールのブローカーがダウンすると、この時点でzookeeper一時ノードが非表示になり、クラスター内の他のブローカーは常にこの一時ノードを監視します。一時ノードが非表示になると、一時ノードの作成を競います。繰り返しになりますが、これは前述の選択メカニズムです。Zookeeperは、ブローカーが新しいコントローラーになることを保証します。

コントローラーIDを持つブローカーは、他の通常のブローカーよりも多くの責任を持つ必要があります。詳細は次のとおりです。

  1. ブローカー関連の変更を監視しますBrokerChangeListenerをZookeeperの/ brokers / ids /ノードに追加して、ブローカーの変更を処理します。
  2. トピック関連の変更を監視します。トピックの増減の変更を処理するためにZookeeperの/ brokers / topicsノードにTopicChangeListenerを追加します。トピックを削除するアクションを処理するためにZookeeperの/ admin / delete_topicsノードにTopicDeletionListenerを追加します。
  3. Zookeeperからトピック、パーティション、ブローカーに関連する現在のすべての情報を読み取り、それに応じて管理します。すべてのトピックに対応するZookeeperの/ brokers / Topics / [topic]ノードにPartitionModificationsListenerを追加して、トピック内のパーティション割り当ての変更を監視します。
  4. クラスターのメタデータ情報を更新し、他の通常のブローカーノードと同期します。

パーティションコピー選出リーダーメカニズム

コントローラーは、パーティションリーダーが配置されているブローカーがダウンしていることを検知し(コントローラーは多くのzkノードを監視し、ブローカーが稼働していることを認識できます)、コントローラーはISRリストから最初のブローカーを選択します(パラメーターの前提の下で) unclean.leader.election.enable = false)リーダーとして(最初のブローカーが最初にISRリストに入れられ、最も同期されたデータを持つコピーである可能性があります)、パラメーターunclean.leader.election.enableがtrueの場合、これは、すべてのコピーがダウンしているときに、ISRリスト内のすべてのコピーをISRに含めることができることを意味します。リーダーはリストにないレプリカから選択されます。この設定により可用性を向上させることができますが、選択された新しいリーダーの数ははるかに少なくなる可能性があります。データ。

コピーがISRリストに入るには、次の2つの条件があります。

  1. レプリカノードはパーティションを生成できず、zookeeperとのセッションを維持し、リーダーレプリカネットワークに接続できる必要があります
  2. レプリカは、リーダーに対するすべての書き込み操作を複製でき、あまり遅れることはありません。(リーダーレプリカと同期して遅れているレプリカは、replica.lag.time.max.ms構成によって決定されます。この時間以降にリーダーと同期しなかったレプリカはISRリストから削除されます)

消費者消費メッセージのオフセット記録メカニズム

各コンシューマーは、自身の消費パーティションのオフセットを定期的にKafkaの内部トピック__consumer_offsetsに送信します。過去を送信する場合、キーはconsumerGroupId + topic + partition numberであり、値は現在のオフセットの値です。Kafkaは定期的に送信します。トピック内のメッセージをクリーンアップし、最後に最新のデータを保持します

 __consumer_offsetsは同時実行性の高い要求を受信する可能性があるため、Kafkaはデフォルトで50個のパーティションを割り当て(offsets.topic.num.partitionsで設定できます)、マシンを追加することで大きな同時実行性に抵抗できます。

次の式を使用して、コンシューマーが__consumer_offsetsに送信するオフセットを消費するパーティションを選択できます。

式:hash(consumerGroupId)%__ consumer_offsetsトピックパーティション番号

消費者リバランスメカニズム

リバランスとは、消費者グループ内の消費者の数が変化した場合、または消費パーティションの数が変化した場合に、Kafkaが消費者消費パーティション間の関係を再配分することを意味します。たとえば、コンシューマーグループのコンシューマーが電話を切ると、そのコンシューマーに割り当てられたパーティションは、この時点で他のコンシューマーに自動的に引き渡されます。彼が再起動すると、一部のパーティションが再び彼に返されます。

注:リバランスはサブスクライブ専用であり、パーティションの消費を指定しません。パーティションが割り当てによって指定された場合、Kafkaはリバンランスを実行しません。

次の状況は、消費者のリバランスを引き起こす可能性があります

  1. 消費者グループの消費者は増減します
  2. トピックにパーティションを動的に追加する
  3. より多くのトピックを購読している消費者グループ

リバランスプロセス中、コンシューマーはKafkaからのメッセージを消費できず、KafkaのTPSに影響を与えます。Kafkaクラスターに数百などのノードが多数ある場合、リバランスに時間がかかる可能性があるため、システムピークリバランスが発生します。

リバランスプロセスは次のとおりです

消費者が消費者グループに参加すると、消費者、消費者グループ、およびグループコーディネーターは次の段階を経ます。

最初の段階:グループコーディネーターを選択します

グループコーディネーター:各コンシューマーグループは、グループコーディネーターコーディネーターとしてブローカーを選択します。ブローカーは、このコンシューマーグループ内のすべてのコンシューマーのハートビートを監視し、ダウンしているかどうかを判断してから、コンシューマーリバランスをオンにします。

コンシューマーグループ内の各コンシューマーが起動すると、Kafkaクラスター内のノードにFindCoordinatorRequest要求を送信して、対応するグループコーディネーターGroupCoordinatorを検索し、ネットワーク接続を確立します。

グループコーディネーターの選択方法:

コンシューマーがオフセットを消費する__consumer_offsetsのどのパーティションに送信する必要があり、このパーティションのリーダーに対応するブローカーがコンシューマーグループのコーディネーターです。

第2段階:消費者グループに参加するJOIN GROUP

コンシューマーグループに対応するGroupCoordinatorが正常に検出されると、コンシューマーグループに参加する段階に入ります。この段階で、コンシューマーはJoinGroupRequest要求をGroupCoordinatorに送信し、応答を処理します。次に、GroupCoordinatorは、コンシューマーグループからグループに参加する最初のコンシューマーをリーダー(コンシューマーグループコーディネーター)として選択し、コンシューマーグループ情報をこのリーダーに送信します。次に、このリーダーがパーティションプランの作成を担当します。

第3段階(SYNC GROUP)

コンシューマーリーダーはSyncGroupRequestをGroupCoordinatorに送信し、GroupCoordinatorはパーティションプランを各コンシューマーに配布し、指定されたパーティションのリーダーブローカーに従ってネットワーク接続とメッセージの消費を実行します。

プロデューサーの公開メッセージメカニズムの分析

0

コンシューマーリバランスパーティション割り当て戦略:

3つの主要なリバランス戦略があります:範囲、ラウンドロビン、およびスティッキー。

Kafkaは、コンシューマーとサブスクリプショントピック間のパーティション割り当て戦略を設定するためのコンシューマークライアントパラメーターpartition.assignment.strategyを提供します。デフォルトは範囲割り当て戦略です。

トピックに10個のパーティション(0〜9)があるとすると、消費者の消費は3つになります。

範囲戦略は、パーティション番号に従ってソートすることです。n=パーティションの数/コンシューマーの数= 3、m =パーティションの数%コンシューマーの数= 1と仮定すると、最初のm個のコンシューマーのそれぞれにn +1が割り当てられます。パーティション、および次の(消費人数-m)コンシューマーには、それぞれn個のパーティションが割り当てられます。

たとえば、パーティション0〜3は1つのコンシューマーに与えられ、ゾーン4〜6は1つのコンシューマーに与えられ、ゾーン7〜9は1つのコンシューマーに与えられます。

ラウンドロビン戦略ラウンドロビン割り当てです。たとえば、パーティション0、3、6、および9はコンシューマーに割り当てられ、パーティション1、4、および7はコンシューマーに割り当てられ、パーティション2、5、および8は消費者に割り当てられます。

スティッキー戦略の初期割り当て戦略はラウンドロビンに似ていますが、リバランス中に、次の2つの原則を保証する必要があります。

1)パーティションの分散は可能な限り均等にする必要があります。

2)可能な限り、パーティションの割り当ては最後の割り当てと同じままです。

2つが競合する場合、最初の目標が2番目の目標よりも優先されます。このようにして、元のパーティション割り当て戦略を最大限に維持できます。

たとえば、最初の範囲のケースの割り当ての場合、3番目のコンシューマーが失敗した場合、スティッキー戦略を使用した再割り当ての結果は次のようになります。

元の0〜3に加えて、consumer1には別の7が割り当てられます

Consumer2は、元の4〜6に加えて、8と9を割り当てます。

プロデューサーの公開メッセージメカニズムの分析

1.書き方

プロデューサーはプッシュモードを使用してブローカーにメッセージを公開し、各メッセージはシーケンシャルディスク書き込みであるパティションに追加されます(シーケンシャルディスク書き込み効率はランダム書き込みメモリよりも高く、Kafkaスループットレートが保証されます)。

2.メッセージルーティング

プロデューサーがブローカーにメッセージを送信すると、パーティションアルゴリズムに従って、メッセージを格納するパーティションが選択されます。ルーティングメカニズムは次のとおりです。

1. patitionが指定されている場合は、直接使用します。2。patitionが指定されていないが、keyが指定されている場合は、キーの値をハッシュしてpatitionを選択します。3。patitionとkeyの両方が指定されていない場合は、ポーリングを使用して世論調査。

3.書き込みプロセス


1.プロデューサーは最初にzookeeperの「/ brokers / ... / state」ノードからパーティションのリーダーを見つけます
2.プロデューサーはメッセージをリーダーに送信します
3.リーダーはメッセージをローカルログに書き込みます
4。フォロワーはリーダーからメッセージをプルして書き込みますローカルログを入力した後、リーダーにACKを送信します
。5 リーダーはISR内のすべてのレプリカのACKを受信した後、HW(最高水準点、最終のオフセット)を追加します。 commit)そして
ACKプロデューサーに送信します

HWとLEOの詳細な説明

HWは一般にHighWatermarkと呼ばれ、HighWatermarkの略です。パーティションに対応するISR内の最小のLEO(ログエンドオフセット)はHWと見なされ、消費者はHWが配置されている場所までしか消費できません。 。さらに、各レプリカにはHWがあり、リーダーとフォロワーはそれぞれのHWステータスを更新する責任があります。リーダーによって新しく書き込まれたメッセージの場合、コンシューマーはすぐにメッセージを消費できません。リーダーは、メッセージがISR内のすべてのレプリカによって同期されるのを待って、HWを更新します。その後、メッセージはコンシューマーによって消費されます。これにより、リーダーが配置されているブローカーに障害が発生した場合でも、新しく選出されたリーダーからメッセージを取得できます。内部ブローカーからの読み取り要求の場合、ハードウェアの制限はありません。

次の図は、プロデューサーがブローカーへのメッセージを生成した後のISR、HW、およびLEOのフローを詳細に示しています。

Kafkaのレプリケーションメカニズムは、完全な同期レプリケーションでも純粋な非同期レプリケーションでもないことがわかります。実際、同期レプリケーションでは、このメッセージがコミットされる前に、動作中のすべてのフォロワーがレプリケートされている必要があります。このレプリケーション方法は、スループットレートに大きく影響します。非同期レプリケーションモードでは、フォロワーはリーダーからのデータを非同期にレプリケートします。データがリーダーによってログに書き込まれている限り、データはコミットされたと見なされます。この場合、フォロワーがまだレプリケートされていない場合は、リーダーが遅れると、リーダーが突然ダウンし、データが失われます。KafkaのISRの使用方法は、データとスループットが失われないようにするためのバランスが取れています。メッセージの永続化メカニズムに対するメッセージ送信者のパラメータacksの設定を確認しましょう。HWとLEOを組み合わせて、acks = 1の場合を見てみましょう。

HWとLEOを組み合わせて、acks = 1の場合を確認します。


ログのセグメンテーション

Kafkaのパーティションのメッセージデータは、トピック名+パーティション番号にちなんで名付けられたフォルダに対応して保存されます。メッセージはパーティション内のセグメントに保存され、各セグメントのメッセージは異なるログファイルに保存されます。この機能は便利です。 Kafkaは、セグメントの最大ログファイルを1Gと規定しています。この制限の目的は、操作のためにログファイルをメモリにロードしやすくすることです。

# 部分消息的offset索引文件,kafka每次往分区发4K(可配置)消息就会记录一条当前消息的offset到index文件,
# 如果要定位消息的offset会先在这个文件里快速定位,再去log文件里找具体消息
00000000000000000000.index
# 消息存储文件,主要存offset和消息体
00000000000000000000.log
# 消息的发送时间索引文件,kafka每次往分区发4K(可配置)消息就会记录一条当前消息的发送时间戳与对应的offset到timeindex文件,
# 如果需要按照时间来定位消息的offset,会先在这个文件里查找
00000000000000000000.timeindex

00000000000005367851.index
00000000000005367851.log
00000000000005367851.timeindex

00000000000009936472.index
00000000000009936472.log
00000000000009936472.timeindex

9936472のようなこの数値は、ログセグメントファイルに含まれる開始オフセットを表します。これは、少なくとも1,000万個近くのデータがこのパーティションに書き込まれたことを意味します。

Kafka Brokerには、各ログセグメントファイルのサイズを制限するパラメータlog.segment.bytesがあります。最大値は1GBです。

ログセグメントファイルがいっぱいになると、新しいログセグメントファイルが自動的に開かれて書き込みが行われるため、1つのファイルが大きくなりすぎて、ファイルの読み取りと書き込みのパフォーマンスに影響を与えることはありません。このプロセスは、ログローリングおよびログセグメントファイルと呼ばれます。書き込まれることは、アクティブログセグメントと呼ばれます。

最後に、zookeeperノードのデータ図が添付されています。

https://note.youdao.com/yws/public/resource/d9fed88c81ff75e6c0e6364012d19fef/xmlnote/2F76FF53FBF643E785B18CD0F0C2D3D2/83219

おすすめ

転載: blog.csdn.net/nmjhehe/article/details/114500875