Kafka之ISR機(jī)制的理解

Kafka對(duì)于producer發(fā)來的消息怎么保證可靠性?
每個(gè)partition都給配上副本,做數(shù)據(jù)同步,保證數(shù)據(jù)不丟失。

副本數(shù)據(jù)同步策略
和zookeeper不同的是,Kafka選擇的是全部完成同步,才發(fā)送ack。但是又有所區(qū)別。

所以,你們才會(huì)在各種博客看到這句話【kafka不是完全同步,也不是完全異步,是一種ISR機(jī)制】

這句話對(duì)也不對(duì),不對(duì)也對(duì)(謎語人......)

首先筆者認(rèn)為:Kafka使用的就是完全同步方案。

完全同步的優(yōu)點(diǎn)
同樣為了容忍 n 臺(tái)節(jié)點(diǎn)的故障,過半機(jī)制需要 2n+1 個(gè)副本,而全部同步方案只需要 n+1 個(gè)副本,

而 Kafka 的每個(gè)分區(qū)都有大量的數(shù)據(jù),過半機(jī)制方案會(huì)造成大量數(shù)據(jù)的冗余。(這就是和zookeeper的不同)

完全同步會(huì)有什么問題?
假設(shè)就有這么一個(gè)follower延遲太高或者某種故障的情況出現(xiàn),導(dǎo)致遲遲不能與leader進(jìn)行同步。

怎么辦?leader等還是不等?

等吧:producer有話要說:“Kafka也不行啊,處理個(gè)消息這么費(fèi)勁,垃圾,你等NM呢等”

不等:那你Kafka對(duì)外說完全同步個(gè)雞兒,你這是完全同步么?

基于此,Kafka的設(shè)計(jì)者和開發(fā)者想出了一個(gè)非常雞賊的點(diǎn)子:ISR

什么是ISR?
先來看幾個(gè)概念

1、AR(Assigned Repllicas)一個(gè)partition的所有副本(就是replica,不區(qū)分leader或follower)

2、ISR(In-Sync Replicas)能夠和 leader 保持同步的 follower + leader本身 組成的集合。

3、OSR(Out-Sync Relipcas)不能和 leader 保持同步的 follower 集合

4、公式:AR = ISR + OSR

所以,看明白了嗎?

Kafka對(duì)外依然可以聲稱是完全同步,但是承諾是對(duì)AR中的所有replica完全同步了嗎?

并沒有。Kafka只保證對(duì)ISR集合中的所有副本保證完全同步。

至于,ISR到底有多少個(gè)follower,那不知道,別問,問就是完全同步,你再問就多了。

這就好比網(wǎng)購買一送一,結(jié)果郵來了一大一小兩個(gè)產(chǎn)品。

你可能覺得有問題,其實(shí)是沒問題的,商家說送的那個(gè)是一模一樣的了嗎?并沒有。

ISR就是這個(gè)道理,Kafka是一定會(huì)保證leader接收到的消息完全同步給ISR中的所有副本。

而最壞的情況下,ISR中只剩leader自己。

基于此,上述完全同步會(huì)出現(xiàn)的問題就不是問題了。

因?yàn)镮SR的機(jī)制就保證了,處于ISR內(nèi)部的follower都是可以和leader進(jìn)行同步的,一旦出現(xiàn)故障或延遲,就會(huì)被踢出ISR。

ISR 的核心就是:動(dòng)態(tài)調(diào)整

總結(jié):Kafka采用的就是一種完全同步的方案,而ISR是基于完全同步的一種優(yōu)化機(jī)制。

follower的作用
讀寫都是由leader處理,follower只是作備份功能,不對(duì)外提供服務(wù)。

什么情況ISR中的replica會(huì)被踢出ISR?
以前有2個(gè)配置

默認(rèn)10000 即 10秒

replica.lag.time.max.ms

允許 follower 副本落后 leader 副本的消息數(shù)量,超過這個(gè)數(shù)量后,follower 會(huì)被踢出 ISR

replica.lag.max.messages
說白了就是一個(gè)衡量leader和follower之間差距的標(biāo)準(zhǔn)。

一個(gè)是基于時(shí)間間隔,一個(gè)是基于消息條數(shù)。

0.9.0.0版本之后,移除了replica.lag.max.messages 配置。

為什么?

因?yàn)閜roducer是可以批量發(fā)送消息的,很容易超過replica.lag.max.messages,那么被踢出ISR的follower就是受了無妄之災(zāi)。

他們都是沒問題的,既沒有出故障也沒高延遲,憑什么被踢?

replica.lag.max.messages調(diào)大呢?調(diào)多大?太大了是否會(huì)有漏網(wǎng)之魚,造成數(shù)據(jù)丟失風(fēng)險(xiǎn)?

這就是replica.lag.max.messages的設(shè)計(jì)缺陷。

replica.lag.time.max.ms的誤區(qū)
【只要在 replica.lag.time.max.ms 時(shí)間內(nèi) follower 有同步消息,即認(rèn)為該 follower 處于 ISR 中】

你去網(wǎng)上看博客,很多博客表達(dá)的就是這個(gè)意思,不過筆者認(rèn)為這么描述很容易誤導(dǎo)初學(xué)者。

那我是不是可以理解為,follower有個(gè)定時(shí)任務(wù),只要在replica.lag.time.max.ms時(shí)間內(nèi)去leader那pull數(shù)據(jù)就行了。

其實(shí)不是的。千萬不要這么認(rèn)為,因?yàn)檫@里還涉及一個(gè)速率問題(你理解為蓄水池一個(gè)放水一個(gè)注水的問題)。

如果leader副本的消息流入速度大于follower副本的拉取速度時(shí),你follower就是實(shí)時(shí)同步有什么用?

典型的出工不出力,消息只會(huì)越差越多,這種follower肯定是要被踢出ISR的。

當(dāng)follower副本將leader副本的LEO之前的日志全部同步時(shí),則認(rèn)為該follower副本已經(jīng)追趕上leader副本。

此時(shí)更新該副本的lastCaughtUpTimeMs標(biāo)識(shí)。

Kafka的副本管理器(ReplicaManager)啟動(dòng)時(shí)會(huì)啟動(dòng)一個(gè)副本過期檢測(cè)的定時(shí)任務(wù),

會(huì)定時(shí)檢查當(dāng)前時(shí)間與副本的lastCaughtUpTimeMs差值是否大于參數(shù)replica.lag.time.max.ms指定的值。

所以replica.lag.time.max.ms的正確理解是:

follower在過去的replica.lag.time.max.ms時(shí)間內(nèi),已經(jīng)追趕上leader一次了。

follower到底出了什么問題?
兩個(gè)方面,一個(gè)是Kafka自身的問題,另一個(gè)是外部原因

Kafka源碼注釋中說明了一般有兩種情況會(huì)導(dǎo)致副本失效:

1、follower副本進(jìn)程卡住,在一段時(shí)間內(nèi)根本沒有想leader副本發(fā)起同步請(qǐng)求,比如頻繁的Full GC。

2、follower副本進(jìn)程同步過慢,在一段時(shí)間內(nèi)都無法追趕上leader副本,比如IO開銷過大。

1、通過工具增加了副本因子,那么新增加的副本在趕上leader副本之前也都是處于失效狀態(tài)的。

2、如果一個(gè)follower副本由于某些原因(比如宕機(jī))而下線,之后又上線,在追趕上leader副本之前也是出于失效狀態(tài)。

什么情況OSR中的replica會(huì)重新加入ISR?
基于上述,replica重新追上了leader,就會(huì)回到ISR中。

相關(guān)的重要概念
需要先明確幾個(gè)概念:

1、LEO(last end offset):

當(dāng)前replica存的最大的offset的下一個(gè)值

2、HW(high watermark):

小于 HW 值的offset所對(duì)應(yīng)的消息被認(rèn)為是“已提交”或“已備份”的消息,才對(duì)消費(fèi)者可見。

假設(shè)ISR中目前有1個(gè)leader,3個(gè)follower。

1、leader接收一個(gè)消息,自己保存后,馬上發(fā)送3個(gè)請(qǐng)求通知3個(gè)follower趕緊保存

2、等待3個(gè)follower響應(yīng)保存成功

3、響應(yīng)producer,消息提交成功

你是這么想的么?反正當(dāng)時(shí)我是這么想的。

實(shí)際上不是的,這個(gè)同步是follower主動(dòng)去請(qǐng)求leader進(jìn)行同步的。

因?yàn)槭敲總€(gè)follower情況不一樣,所以才會(huì)出現(xiàn)LEO和HW的概念。

簡(jiǎn)言之,木桶原理

replica里存了多少數(shù)據(jù)和consumer能消費(fèi)多少數(shù)據(jù),不是一回事。

所謂木桶原理,就是把每個(gè)replica當(dāng)作一個(gè)木桶的板子,桶能裝多少水只取決于最短的那塊板子。

這就是也有些人把HW叫成 高水位 的原因。

而 HW 的概念,也契合前文提到的【完全同步】,HW之前的所有消息,在ISR中是完全同步的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容