04斤儿、關(guān)于高水位和Leader Epoch

在 Kafka 中,高水位的作用主要有 2 個(gè)恐锦。

  1. 定義消息可見(jiàn)性往果,即用來(lái)標(biāo)識(shí)分區(qū)下的哪些消息是可以被消費(fèi)者消費(fèi)的。
  2. 幫助 Kafka 完成副本同步一铅。

下面這張圖展示了多個(gè)與高水位相關(guān)的 Kafka 術(shù)語(yǔ)陕贮。我來(lái)詳細(xì)解釋一下圖中的內(nèi)容,同時(shí)澄清一些常見(jiàn)的誤區(qū)馅闽。


位移值等于高水位的消息也屬于未提交消息飘蚯。也就是說(shuō)馍迄,高水位上的消息是不能被消費(fèi)者消費(fèi)的福也。

Log End Offset,簡(jiǎn)寫(xiě)是 LEO攀圈。它表示副本寫(xiě)入下一條消息的位移值暴凑。

介于高水位和 LEO 之間的消息就屬于未提交消息。這也從側(cè)面告訴了我們一個(gè)重要的事實(shí)赘来,那就是:同一個(gè)副本對(duì)象现喳,其高水位值不會(huì)大于 LEO 值凯傲。



什么叫與 Leader 副本保持同步。判斷的條件有兩個(gè)嗦篱。

  1. 該遠(yuǎn)程 Follower 副本在 ISR 中冰单。
  2. 該遠(yuǎn)程 Follower 副本 LEO 值落后于 Leader 副本 LEO 值的時(shí)間,不超過(guò) Broker 端參數(shù) replica.lag.time.max.ms 的值灸促。如果使用默認(rèn)值的話诫欠,就是不超過(guò) 10 秒

副本同步機(jī)制解析

當(dāng)生產(chǎn)者發(fā)送一條消息時(shí),Leader 和 Follower 副本對(duì)應(yīng)的高水位是怎么被更新的呢浴栽?我給出了一些圖片荒叼,我們一一來(lái)看。

首先是初始狀態(tài)典鸡。下面這張圖中的 remote LEO 就是剛才的遠(yuǎn)程副本的 LEO 值被廓。在初始狀態(tài)時(shí),所有值都是 0萝玷。

當(dāng)生產(chǎn)者給主題分區(qū)發(fā)送一條消息后嫁乘,狀態(tài)變更為:

此時(shí),Leader 副本成功將消息寫(xiě)入了本地磁盤(pán)间护,故 LEO 值被更新為 1亦渗。

Follower 再次嘗試從 Leader 拉取消息。和之前不同的是汁尺,這次有消息可以拉取了法精,因此狀態(tài)進(jìn)一步變更為:

這時(shí),F(xiàn)ollower 副本也成功地更新 LEO 為 1痴突。此時(shí)搂蜓,Leader 和 Follower 副本的 LEO 都是 1,但各自的高水位依然是 0辽装,還沒(méi)有被更新帮碰。它們需要在下一輪的拉取中被更新,如下圖所示:

在新一輪的拉取請(qǐng)求中拾积,由于位移值是 0 的消息已經(jīng)拉取成功殉挽,因此 Follower 副本這次請(qǐng)求拉取的是位移值 =1 的消息。Leader 副本接收到此請(qǐng)求后拓巧,更新遠(yuǎn)程副本 LEO 為 1斯碌,然后更新 Leader 高水位為 1。做完這些之后肛度,它會(huì)將當(dāng)前已更新過(guò)的高水位值 1 發(fā)送給 Follower 副本傻唾。Follower 副本接收到以后,也將自己的高水位值更新成 1承耿。至此冠骄,一次完整的消息同步周期就結(jié)束了伪煤。事實(shí)上,Kafka 就是利用這樣的機(jī)制凛辣,實(shí)現(xiàn)了 Leader 和 Follower 副本之間的同步抱既。

Leader Epoch 登場(chǎng)

我們知道,F(xiàn)ollower 副本的高水位更新需要一輪額外的拉取請(qǐng)求才能實(shí)現(xiàn)扁誓。如果把上面那個(gè)例子擴(kuò)展到多個(gè) Follower 副本蝙砌,情況可能更糟,也許需要多輪拉取請(qǐng)求跋理。也就是說(shuō)择克,Leader 副本高水位更新和 Follower 副本高水位更新在時(shí)間上是存在錯(cuò)配的。這種錯(cuò)配是很多“數(shù)據(jù)丟失”或“數(shù)據(jù)不一致”問(wèn)題的根源前普《切希基于此,社區(qū)在 0.11 版本正式引入了 Leader Epoch 概念拭卿,來(lái)規(guī)避因高水位更新錯(cuò)配導(dǎo)致的各種不一致問(wèn)題骡湖。

所謂 Leader Epoch,我們大致可以認(rèn)為是 Leader 版本峻厚。它由兩部分?jǐn)?shù)據(jù)組成响蕴。

  1. Epoch。一個(gè)單調(diào)增加的版本號(hào)惠桃。每當(dāng)副本領(lǐng)導(dǎo)權(quán)發(fā)生變更時(shí)浦夷,都會(huì)增加該版本號(hào)。小版本號(hào)的 Leader 被認(rèn)為是過(guò)期 Leader辜王,不能再行使 Leader 權(quán)力劈狐。
  2. 起始位移(Start Offset)。Leader 副本在該 Epoch 值上寫(xiě)入的首條消息的位移呐馆。

我舉個(gè)例子來(lái)說(shuō)明一下 Leader Epoch肥缔。假設(shè)現(xiàn)在有兩個(gè) Leader Epoch<0, 0> 和 <1, 120>,那么汹来,第一個(gè) Leader Epoch 表示版本號(hào)是 0续膳,這個(gè)版本的 Leader 從位移 0 開(kāi)始保存消息,一共保存了 120 條消息收班。之后坟岔,Leader 發(fā)生了變更,版本號(hào)增加到 1闺阱,新版本的起始位移是 120炮车。

Kafka Broker 會(huì)在內(nèi)存中為每個(gè)分區(qū)都緩存 Leader Epoch 數(shù)據(jù)舵变,同時(shí)它還會(huì)定期地將這些信息持久化到一個(gè) checkpoint 文件中酣溃。當(dāng) Leader 副本寫(xiě)入消息到磁盤(pán)時(shí)瘦穆,Broker 會(huì)嘗試更新這部分緩存。如果該 Leader 是首次寫(xiě)入消息赊豌,那么 Broker 會(huì)向緩存中增加一個(gè) Leader Epoch 條目扛或,否則就不做更新。這樣碘饼,每次有 Leader 變更時(shí)熙兔,新的 Leader 副本會(huì)查詢(xún)這部分緩存,取出對(duì)應(yīng)的 Leader Epoch 的起始位移艾恼,以避免數(shù)據(jù)丟失和不一致的情況住涉。

接下來(lái),我們來(lái)看一個(gè)實(shí)際的例子钠绍,它展示的是 Leader Epoch 是如何防止數(shù)據(jù)丟失的舆声。請(qǐng)先看下圖。

我稍微解釋一下柳爽,單純依賴(lài)高水位是怎么造成數(shù)據(jù)丟失的媳握。開(kāi)始時(shí),副本 A 和副本 B 都處于正常狀態(tài)磷脯,A 是 Leader 副本蛾找。某個(gè)使用了默認(rèn) acks 設(shè)置的生產(chǎn)者程序向 A 發(fā)送了兩條消息,A 全部寫(xiě)入成功赵誓,此時(shí) Kafka 會(huì)通知生產(chǎn)者說(shuō)兩條消息全部發(fā)送成功打毛。

現(xiàn)在我們假設(shè) Leader 和 Follower 都寫(xiě)入了這兩條消息,而且 Leader 副本的高水位也已經(jīng)更新了俩功,但 Follower 副本高水位還未更新——這是可能出現(xiàn)的隘冲。還記得吧,F(xiàn)ollower 端高水位的更新與 Leader 端有時(shí)間錯(cuò)配绑雄。倘若此時(shí)副本 B 所在的 Broker 宕機(jī)展辞,當(dāng)它重啟回來(lái)后,副本 B 會(huì)執(zhí)行日志截?cái)嗖僮魍蛭瑢?LEO 值調(diào)整為之前的高水位值罗珍,也就是 1。這就是說(shuō)脚粟,位移值為 1 的那條消息被副本 B 從磁盤(pán)中刪除覆旱,此時(shí)副本 B 的底層磁盤(pán)文件中只保存有 1 條消息,即位移值為 0 的那條消息核无。

當(dāng)執(zhí)行完截?cái)嗖僮骱罂鄢北?B 開(kāi)始從 A 拉取消息,執(zhí)行正常的消息同步。如果就在這個(gè)節(jié)骨眼上噪沙,副本 A 所在的 Broker 宕機(jī)了炼彪,那么 Kafka 就別無(wú)選擇,只能讓副本 B 成為新的 Leader正歼,此時(shí)辐马,當(dāng) A 回來(lái)后,需要執(zhí)行相同的日志截?cái)嗖僮骶忠澹磳⒏咚徽{(diào)整為與 B 相同的值喜爷,也就是 1。這樣操作之后萄唇,位移值為 1 的那條消息就從這兩個(gè)副本中被永遠(yuǎn)地抹掉了檩帐。這就是這張圖要展示的數(shù)據(jù)丟失場(chǎng)景。

嚴(yán)格來(lái)說(shuō)另萤,這個(gè)場(chǎng)景發(fā)生的前提是Broker 端參數(shù) min.insync.replicas 設(shè)置為 1轿塔。此時(shí)一旦消息被寫(xiě)入到 Leader 副本的磁盤(pán),就會(huì)被認(rèn)為是“已提交狀態(tài)”仲墨,但現(xiàn)有的時(shí)間錯(cuò)配問(wèn)題導(dǎo)致 Follower 端的高水位更新是有滯后的勾缭。如果在這個(gè)短暫的滯后時(shí)間窗口內(nèi),接連發(fā)生 Broker 宕機(jī)目养,那么這類(lèi)數(shù)據(jù)的丟失就是不可避免的俩由。

現(xiàn)在,我們來(lái)看下如何利用 Leader Epoch 機(jī)制來(lái)規(guī)避這種數(shù)據(jù)丟失癌蚁。我依然用圖的方式來(lái)說(shuō)明幻梯。

場(chǎng)景和之前大致是類(lèi)似的,只不過(guò)引用 Leader Epoch 機(jī)制后努释,F(xiàn)ollower 副本 B 重啟回來(lái)后碘梢,需要向 A 發(fā)送一個(gè)特殊的請(qǐng)求去獲取 Leader 的 LEO 值。在這個(gè)例子中伐蒂,該值為 2煞躬。當(dāng)獲知到 Leader LEO=2 后,B 發(fā)現(xiàn)該 LEO 值不比它自己的 LEO 值小逸邦,而且緩存中也沒(méi)有保存任何起始位移值 > 2 的 Epoch 條目恩沛,因此 B 無(wú)需執(zhí)行任何日志截?cái)嗖僮鳌_@是對(duì)高水位機(jī)制的一個(gè)明顯改進(jìn)缕减,即副本是否執(zhí)行日志截?cái)嗖辉僖蕾?lài)于高水位進(jìn)行判斷雷客。

現(xiàn)在,副本 A 宕機(jī)了桥狡,B 成為 Leader搅裙。同樣地皱卓,當(dāng) A 重啟回來(lái)后,執(zhí)行與 B 相同的邏輯判斷部逮,發(fā)現(xiàn)也不用執(zhí)行日志截?cái)嗄戎链宋灰浦禐?1 的那條消息在兩個(gè)副本中均得到保留。后面當(dāng)生產(chǎn)者程序向 B 寫(xiě)入新消息時(shí)甥啄,副本 B 所在的 Broker 緩存中,會(huì)生成新的 Leader Epoch 條目:[Epoch=1, Offset=2]炬搭。之后蜈漓,副本 B 會(huì)使用這個(gè)條目幫助判斷后續(xù)是否執(zhí)行日志截?cái)嗖僮鳌_@樣宫盔,通過(guò) Leader Epoch 機(jī)制融虽,Kafka 完美地規(guī)避了這種數(shù)據(jù)丟失場(chǎng)景。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末灼芭,一起剝皮案震驚了整個(gè)濱河市有额,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌彼绷,老刑警劉巖巍佑,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異寄悯,居然都是意外死亡萤衰,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)猜旬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)脆栋,“玉大人,你說(shuō)我怎么就攤上這事洒擦〈徽” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵熟嫩,是天一觀的道長(zhǎng)秦踪。 經(jīng)常有香客問(wèn)我,道長(zhǎng)掸茅,這世上最難降的妖魔是什么洋侨? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮倦蚪,結(jié)果婚禮上希坚,老公的妹妹穿的比我還像新娘。我一直安慰自己陵且,他們只是感情好裁僧,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布个束。 她就那樣靜靜地躺著,像睡著了一般聊疲。 火紅的嫁衣襯著肌膚如雪茬底。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天获洲,我揣著相機(jī)與錄音阱表,去河邊找鬼。 笑死贡珊,一個(gè)胖子當(dāng)著我的面吹牛最爬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播门岔,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼爱致,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了寒随?” 一聲冷哼從身側(cè)響起糠悯,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎妻往,沒(méi)想到半個(gè)月后互艾,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡讯泣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年忘朝,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片判帮。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡局嘁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晦墙,到底是詐尸還是另有隱情悦昵,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布晌畅,位于F島的核電站但指,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏抗楔。R本人自食惡果不足惜棋凳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望连躏。 院中可真熱鬧剩岳,春花似錦、人聲如沸入热。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至绰播,卻和暖如春骄噪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蠢箩。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工链蕊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人谬泌。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓滔韵,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親呵萨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子奏属,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349