kafka的HA設(shè)計(jì)

kafka的HA設(shè)計(jì)

1.選舉算法

replica,ISR(oh my all?。?/b>。replica(消息的副本)設(shè)計(jì)是partition最重要的概念,副本機(jī)制是很多分布式數(shù)據(jù)系統(tǒng)實(shí)現(xiàn)高可用的常用方法。以下直接參考的一篇博文,看下了,基本上是翻譯的官方文檔,表達(dá)很準(zhǔn)確。再熟悉下partition和replica的關(guān)系。

3個(gè)partition,3個(gè)replica,4個(gè)broker分配情況

partition和replica默認(rèn)分配到哪個(gè)broker的策略是:

將所有N Broker和待分配的i個(gè)Partition排序.

將第i個(gè)Partition分配到第(i mod n)個(gè)Broker上.

將第i個(gè)Partition的第j個(gè)副本分配到第((i + j) mod n)個(gè)Broker上.

客戶(hù)端生產(chǎn)消費(fèi)消息都是只跟leader交互,這一點(diǎn)設(shè)計(jì)跟有些分布式系統(tǒng)有所不用(比如zk設(shè)計(jì)寫(xiě)操作只能在leader交互,讀操作可以是leader也可以是follower)。個(gè)人認(rèn)為主要還是考慮到實(shí)現(xiàn)上簡(jiǎn)單。

leader是對(duì)應(yīng)partition的概念,每個(gè)partition都有一個(gè)leader。

ISR

zookeeper的Zab協(xié)議算法是這個(gè)Majority Vote的類(lèi)型,raft也是。而Kafka所使用的這種ISR概念的算法更像微軟的PacificA算法。

ISR(In-Sync Replicas)直譯就是跟上leader的副本

是怎樣使用ISR概念,在Follower中選舉出新的Leader昵?

選leader一個(gè)基本的原則就是,如果Leader不在了,新的Leader必須擁有原來(lái)的Leader commit過(guò)的所有消息。ISR列表里的副本都跟上了leader,所以就是在這里邊選一個(gè)。

那如何維護(hù)這個(gè)ISR列表就是算法要實(shí)現(xiàn)的核心內(nèi)容。

producer寫(xiě)數(shù)據(jù)到leader,那副本是如何同步數(shù)據(jù)的昵?

副本(replica)有單獨(dú)的fetch線程去拉取同步消息。拉取的時(shí)間間隔可配置。

一條消息上的一些概念

High watermark(高水位線)以下簡(jiǎn)稱(chēng)HW,表示消息被leader和ISR內(nèi)的follow都確認(rèn)commit寫(xiě)入本地log,所以在HW位置以下的消息都可以被消費(fèi)(不會(huì)丟失)。

Log end offset(日志結(jié)束位置)以下簡(jiǎn)稱(chēng)LEO,表示消息的最后位置。LEO>=HW,一般會(huì)有沒(méi)提交的部分。

ISR概念的引入就在這里。

副本會(huì)有單獨(dú)的線程(ReplicaFetcherThread),去從leader上去拉去消息同步。當(dāng)follower的HW趕上leader的,就會(huì)保持或加入到ISR列表里,就說(shuō)明此follower滿(mǎn)足上述最基本的原則(跟上leader進(jìn)度)。ISR列表存在zookeeper上。

topic下某個(gè)partition的ISR存儲(chǔ)位置

那如何確定follower趕上leader進(jìn)度昵?

有兩參數(shù)決定是否"趕上"

replica.lag.max.messages 落后的消息個(gè)數(shù)

replica.lag.time.max.ms 多長(zhǎng)時(shí)間沒(méi)有發(fā)送FetchQuest請(qǐng)求拉去leader數(shù)據(jù)

比如落后消息達(dá)到設(shè)置的100,10s中沒(méi)有再發(fā)送FetchRequest請(qǐng)求,就會(huì)從ISR列表中移除。

有了兩個(gè)參數(shù)概念,可應(yīng)該能理解,replica.fetch.wait.max.ms(默認(rèn)10s)這個(gè)參數(shù)是發(fā)送fetchRequest頻率(最大等待時(shí)間),這個(gè)值要始終小于replica.lag.time.max.ms(默認(rèn)500ms),以保證replica不會(huì)被頻繁的移除ISR

參數(shù)官方解釋見(jiàn)http://kafka.apache.org/documentation/

kafka新版本對(duì)這兩個(gè)參數(shù)做了優(yōu)化,移除了落后消息個(gè)數(shù)參數(shù)(replica.lag.max.messages),原因是這個(gè)值不好把控,需要經(jīng)驗(yàn)值,不用的業(yè)務(wù)服務(wù)器環(huán)境,這個(gè)值可能不同,不然會(huì)頻繁的移除加入ISR列表。細(xì)節(jié)分析推薦參考博文

0.9后不再使用replica.lag.max.messages參數(shù)

舉個(gè)??,正常運(yùn)行時(shí),如下圖

follower跟上的leader,HW是6

當(dāng)follow可能的IO耗時(shí)過(guò)高,經(jīng)歷了一次full gc耗時(shí)很多時(shí),達(dá)到了上述兩個(gè)條件,follow被移除了ISR列表。此時(shí)的HW還是6,leader上的LEO是10。消費(fèi)者只能消費(fèi)offset到6。

兩個(gè)副本移除了ISR列表

設(shè)計(jì)好如何維護(hù)一個(gè)ISR列表,就完成這個(gè)算法主要的工作。完成上述過(guò)程,維護(hù)了一個(gè)ISR列表,就能保證leader不可用時(shí),可以從ISR中選一個(gè)replica作為leader繼續(xù)工作。


cap理論,在分布式系統(tǒng)下,要在a高可用性和c一致可靠性做個(gè)折衷

知道上述設(shè)計(jì),而為了讓ISR能一直有replica,保證正常的HA,這就需要作一個(gè)折衷。

如果Leader在一條消息被commit前等待更多的Follower確認(rèn),那在它宕機(jī)之后就有更多的Follower可以作為新的Leader,但這也會(huì)造成吞吐率的下降。

所以有了producer的ack參數(shù)選擇,取優(yōu)先考慮可靠性,還是優(yōu)先考慮高并發(fā)。以下不用的參數(shù),會(huì)導(dǎo)致有可能丟消息。

0表示純異步,不等待,寫(xiě)進(jìn)socket buffer就繼續(xù)。

1表示leader寫(xiě)進(jìn)server的本地log,就返回,不等待follower的回應(yīng)。

-1相當(dāng)于all,表示等待follower回應(yīng)再繼續(xù)發(fā)消息。保證了ISR列表里至少有一個(gè)replica,數(shù)據(jù)就不會(huì)丟失,最高的保證級(jí)別。


跟Majority Vote算法的比較理解

常見(jiàn)的leader的選舉算法還有Majority Vote(少數(shù)服從多數(shù)),但Kafka并未采用這種方式。比較一下兩種算法:

Majority Vote:如果我們有2f+1個(gè)Replica(包含Leader和Follower),那在commit之前必須保證有f+1個(gè)Replica復(fù)制完消息,為了保證正確選出新的Leader,fail的Replica不能超過(guò)f個(gè)。因?yàn)樵谑O碌娜我鈌+1個(gè)Replica里,至少有一個(gè)Replica包含有最新的所有消息。

優(yōu)點(diǎn)是,系統(tǒng)的潛力只取決于最快的幾個(gè)Broker,而非最慢那個(gè)

劣勢(shì)是,同等數(shù)量的機(jī)器,它所能容忍的fail的follower個(gè)數(shù)比較少。比如:如果要容忍1個(gè)follower掛掉,必須要有3個(gè)以上的Replica,如果要容忍2個(gè)Follower掛掉,必須要有5個(gè)以上的Replica。

結(jié)論是:就是這種算法更多用在Zookeeper這種共享集群配置的系統(tǒng)中使用,而很少在需要存儲(chǔ)大量數(shù)據(jù)的系統(tǒng)中使用的原因。

Kafka在Zookeeper中動(dòng)態(tài)維護(hù)了一個(gè)ISR(in-sync replicas),這個(gè)ISR里的所有Replica都跟上了leader,只有ISR里的成員才有被選為L(zhǎng)eader的可能。

優(yōu)點(diǎn):在這種模式下,對(duì)于f+1個(gè)Replica,一個(gè)Partition能在保證不丟失已經(jīng)commit的消息的前提下容忍f個(gè)Replica的失敗。

缺點(diǎn):相應(yīng)的,leader需要等待最慢的那個(gè)replica,但是Kafka作者認(rèn)為Kafka可以通過(guò)Producer選擇是否被commit阻塞來(lái)改善這一問(wèn)題,trade-off就是節(jié)省下來(lái)的Replica和磁盤(pán)。



ISR至少有一個(gè)replica,能保證不丟消息,如果ISR里的副本都被移除了怎么處理呢?

有兩種方式,這就需要在可用性與一致性做個(gè)妥協(xié)。

等待ISR中的任一個(gè)Replica“活”過(guò)來(lái),并且選它作為L(zhǎng)eader

選擇第一個(gè)“活”過(guò)來(lái)的Replica(不一定是ISR中的)作為L(zhǎng)eader

選擇第一種方式,有可能要等很長(zhǎng)時(shí)間;選第二種方式會(huì)丟消息,但是能很快響應(yīng)。

服務(wù)端提供參數(shù)unclean.leader.election.enable選擇上述方式

默認(rèn)是true,表示允許不在ISR列表的follower,選舉為leader(最壞的打算,可能丟消息)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容