詳述カフカ(X)高水位とリーダーエポック詳細

1.高水位

高い水の1.1役割

カフカでは、高水位の役割は、主に2つを持っています

  • 視認性は、パーティションの下でメッセージが消費者によって消費することができるかを識別するために使用されるメッセージを定義します。
  • カフカの同期のヘルプ完全なコピー

この図は、カフカ高い水に関連する以下の用語の複数を示します。

これは、パーティションのリーダーコピーのハイレベル図であると仮定。まず、図は「ニュースを提出されました」とそのノート「未コミットメッセージを。」彼は特に2間の区別をするために、カフカの永続的なセキュリティの話を聞いたときに先立ち。さて、もう一度強調する。パーティションの高水位のメッセージが送信されたメッセージであると考えられ、逆にコミットされていないメッセージです。

情報のみを消費することができる消費者は、図8の変位よりも、すべてのメッセージ少ない、つまり、送信されました。注トランザクションメカニズムがメッセージを見ることができ、消費者の範囲に影響を与えますので、ここで我々はカフカのトランザクションを議論していないこと、それは単純に高レベルの裁判官に依存しません。これは、トランザクションの消費者の可視性を決定するために呼び出される変位値LSO(ログ安定オフセット)に依存しています。

さらに、シフト値は、メッセージ未コミットメッセージ高い水位に等しいです。換言すれば、高水にメッセージを消費者に消費することができません

1.2ログエンドオフセット(LEO)

ログインエンドオフセット(LEO)は、次のメッセージの書き込みシフト値のコピーを表します。メモ、新しいメッセージの変位は15現在のメッセージ15、0から14までの変位値の唯一のコピーであることを示し、点線、デジタルブロック15、すなわち。明らかに、ハイレベルの間に介在し、メッセージはLEOコミットされていないメッセージに属します。また、私たちにある側からの重要な事実を伝えます:オブジェクトのコピーと、その値が高水LEO値よりも大きくありません

高い水とLEOは、2つの重要な属性は、オブジェクトのコピーですカフカは、すべてのコピーに対応する高水とLEO値を持っている、ちょうどリーダーをコピーしません。ただ、リーダーの特別な、パーティションの高水位を定義するために、高い水利用のカフカリーダーのコピーをコピーします。言い換えれば、高水位は、その高水分配リーダーコピーです

2.高水位とLEO更新メカニズム

今、私たちは、オブジェクトの各コピーは、値のセットと高い水LEO値を保持していることを知っているが、実際には、ブローカーリーダーコピーが配置されている中で、また、LEO値HWや他のフォロワーのコピーを保持しています。

図の上方に示されるようにのみ1ブローカフォロワパーティションのコピーを保存しながら、ブローカLEO 0値とパーティションコピーリーダーフォロワのすべてのコピーが格納されています。カフカこれらのフォロワーは、リモートコピー(リモートレプリカ)として知られ、ブローカー0のコピーを保存します。動作中のメカニズムのカフカのコピー、高水位及びブローカーLEOはフォロワー1コピー値、だけでなく、ブローカー0リーダーコピーのハイウォーターマークとすべてのLEOとLEOのリモートコピーを更新するが、それは、リモートコピーを更新しない更新Iは、図中の灰色でマークされた部分である高水位。

リモート主な機能のコピー保存高水分配されており、その高いウォーターマークのリーダーコピーを決定するのを助けるためにあります。以下は、同期メカニズムのコピーは次のとおりです。

2.1リーダーはペースを維持するためにコピーします

リーダーと同期保持の決意条件の2つのコピー:

  1. リモートフォロワーは、ISRにコピーします。
  2. 値のコピーの背後にあるリモートコピーフォロワーリーダーLEO LEO時間値、ブローカー(デフォルト10秒)を終了し、パラメータreplica.lag.time.max.msの値を超えません

2.2更新機構

2.2.1リーダーのコピー

ロジック・プロデューサーの要求:

ローカルディスクへの書き込み1.メッセージ。

2.アップデートの高水分配値。

    i. 获取 Leader 副本所在 Broker 端保存的所有远程副本 LEO 值(LEO-1,LEO-2,……,LEO-n)。

    ii. 获取 Leader 副本高水位值:currentHW。

    iii. 更新 currentHW = max{currentHW, min(LEO-1, LEO-2, ……,LEO-n)}。

处理 Follower 副本拉取消息的逻辑如下:

1. 读取磁盘(或页缓存)中的消息数据。

2. 使用 Follower 副本发送请求中的位移值更新远程副本 LEO 值。

3. 更新分区高水位值(具体步骤与处理生产者请求的步骤相同)。

2.2.2 Follower副本

从 Leader 拉取消息的处理逻辑如下:

1. 写入消息到本地磁盘。

2. 更新 LEO 值。更新高水位值。

    i. 获取 Leader 发送的高水位值:currentHW。

    ii. 获取步骤 2 中更新过的 LEO 值:currentLEO。

    iii. 更新高水位为 min(currentHW, currentLEO)。

3.  副本同步全流程

当生产者发送一条消息时,Leader 和 Follower 副本对应的高水位是怎么被更新的呢?

首先是初始状态。下面这张图中的 remote LEO 就是刚才的远程副本的 LEO 值。在初始状态时,所有值都是 0。

当生产者给主题分区发送一条消息后,状态变更为:

此时,Leader 副本成功将消息写入了本地磁盘,故 LEO 值被更新为 1。

Follower 再次尝试从 Leader 拉取消息。和之前不同的是,这次有消息可以拉取了,因此状态进一步变更为:

这时,Follower 副本也成功地更新 LEO 为 1。此时,Leader 和 Follower 副本的 LEO 都是 1,但各自的高水位依然是 0,还没有被更新。它们需要在下一轮的拉取中被更新,如下图所示:

在新一轮的拉取请求中,由于位移值是 0 的消息已经拉取成功,因此 Follower 副本这次请求拉取的是位移值 =1 的消息。Leader 副本接收到此请求后,更新远程副本 LEO 为 1,然后更新 Leader 高水位为 1。做完这些之后,它会将当前已更新过的高水位值 1 发送给 Follower 副本。Follower 副本接收到以后,也将自己的高水位值更新成 1。至此,一次完整的消息同步周期就结束了。事实上,Kafka 就是利用这样的机制,实现了 Leader 和 Follower 副本之间的同步。

4. Leader Epoch

从刚才的分析中,我们知道,Follower 副本的高水位更新需要一轮额外的拉取请求才能实现。如果把上面那个例子扩展到多个 Follower 副本,情况可能更糟,也许需要多轮拉取请求。也就是说,Leader 副本高水位更新和 Follower 副本高水位更新在时间上是存在错配的。这种错配是很多“数据丢失”或“数据不一致”问题的根源。基于此,社区在 0.11 版本正式引入了 Leader Epoch 概念,来规避因高水位更新错配导致的各种不一致问题。

所谓 Leader Epoch,我们大致可以认为是 Leader 版本。它由两部分数据组成。

  1. Epoch。一个单调增加的版本号。每当副本领导权发生变更时,都会增加该版本号。小版本号的 Leader 被认为是过期 Leader,不能再行使 Leader 权力。
  2. 起始位移(Start Offset)。Leader 副本在该 Epoch 值上写入的首条消息的位移。

举个例子来说明一下 Leader Epoch。假设现在有两个 Leader Epoch<0, 0> 和 <1, 120>,那么,第一个 Leader Epoch 表示版本号是 0,这个版本的 Leader 从位移 0 开始保存消息,一共保存了 120 条消息。之后,Leader 发生了变更,版本号增加到 1,新版本的起始位移是 120。

Kafka Broker 会在内存中为每个分区都缓存 Leader Epoch 数据,同时它还会定期地将这些信息持久化到一个 checkpoint 文件中。当 Leader 副本写入消息到磁盘时,Broker 会尝试更新这部分缓存。如果该 Leader 是首次写入消息,那么 Broker 会向缓存中增加一个 Leader Epoch 条目,否则就不做更新。这样,每次有 Leader 变更时,新的 Leader 副本会查询这部分缓存,取出对应的 Leader Epoch 的起始位移,以避免数据丢失和不一致的情况。

接下来看一个实际的例子,它展示的是 Leader Epoch 是如何防止数据丢失的。

引用 Leader Epoch 机制后,Follower 副本 B 重启回来后,需要向 A 发送一个特殊的请求去获取 Leader 的 LEO 值。在这个例子中,该值为 2。当获知到 Leader LEO=2 后,B 发现该 LEO 值不比它自己的 LEO 值小,而且缓存中也没有保存任何起始位移值 > 2 的 Epoch 条目,因此 B 无需执行任何日志截断操作。这是对高水位机制的一个明显改进,即副本是否执行日志截断不再依赖于高水位进行判断。

现在,副本 A 宕机了,B 成为 Leader。同样地,当 A 重启回来后,执行与 B 相同的逻辑判断,发现也不用执行日志截断,至此位移值为 1 的那条消息在两个副本中均得到保留。后面当生产者程序向 B 写入新消息时,副本 B 所在的 Broker 缓存中,会生成新的 Leader Epoch 条目:[Epoch=1, Offset=2]。之后,副本 B 会使用这个条目帮助判断后续是否执行日志截断操作。这样,通过 Leader Epoch 机制,Kafka 完美地规避了这种数据丢失场景。

发布了8 篇原创文章 · 获赞 0 · 访问量 7275

おすすめ

転載: blog.csdn.net/fedorafrog/article/details/104100235
おすすめ