Kafka消息的可靠傳遞和保證機制

這段時間一直斷斷續(xù)續(xù)地在看《Kafka權(quán)威指南》,深深為Kafka里面的架構(gòu)設(shè)計理念所折服。一邊看的同時一邊設(shè)想面試的時候可能會被問到的問題,恰巧前段時間碰到一道阿里的面試題浦辨,Kafka什么情況下會丟消息。這其實是一道很綜合的題目沼沈,既考察了Kafka服務(wù)端的整體架構(gòu)流酬,又抓住了消息數(shù)據(jù)傳遞過程,對于服務(wù)端數(shù)據(jù)同步或重啟列另、生產(chǎn)者生產(chǎn)請求的回包方式芽腾、消費者提交已消費的位置到服務(wù)端的時機可能出現(xiàn)的所有情況,這些很細節(jié)又很關(guān)鍵的步驟進行考察页衙。

一摊滔、深入Kafka

Kafka 的主題被分為多個分區(qū)阴绢,分區(qū)是基本的數(shù)據(jù)塊。分區(qū)存儲在單個磁盤上艰躺, Kafka 可以保證分區(qū)里的事件是有序的呻袭,分區(qū)可以在線(可用),也可以離線(不可用) 腺兴。每個分區(qū)可以有多個副本左电,其中一個副本是首領(lǐng)。

Kafka服務(wù)端粗略架構(gòu)

Kafka 的復(fù)制機制和分區(qū)的多副本架構(gòu)是Kafka 可靠性保證的核心页响。Kafka分區(qū)的副本分為兩類:首領(lǐng)副本(也就是首領(lǐng))篓足,負責接收所有的讀請求和寫請求。跟隨者副本(跟隨者)拘泞,負責同步首領(lǐng)副本的所有消息纷纫。

當Kafka初始化時,第一個啟動的broker會在Zookeeper上注冊控制節(jié)點成為控制器陪腌,后來的broker通過watch對象監(jiān)控控制器節(jié)點是否消失辱魁。當控制器broker掛掉時,其他broker監(jiān)測后會像zk發(fā)送申請注冊控制器節(jié)點的請求诗鸭。第一個到達的請求會成為控制器染簇。控制器的主要功能就是負責分區(qū)首領(lǐng)的選舉强岸,一旦有broker宕機锻弓,意味著有些分區(qū)會失去首領(lǐng),這個時候由控制器遍歷這些分區(qū)蝌箍,并確定哪些主題的哪些分區(qū)成為首領(lǐng)青灼。

簡而言之, Kafka 使用Zookeeper 的臨時節(jié)點來選舉控制器妓盲, 并在節(jié)點加入集群或退出集群時通知控制器杂拨。控制器負責在節(jié)點加入或離開集群時進行分區(qū)首領(lǐng)選舉悯衬〉粒控制器使用epoch 來避免“腦裂” 〗畲郑“腦裂”是指兩個節(jié)點同時認為自己是當前的控制器策橘。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?——Kafka權(quán)威指南

物理存儲上,Kafka 的基本存儲單元是分區(qū)娜亿。分區(qū)不會在多個broker 間進行再細分丽已,也不會在同一個broker 的多個磁盤上進行再細分。對于分區(qū)的分配买决,Kafka會遵從的兩個原則沛婴,其一是首領(lǐng)副本和跟隨者副本盡量不要在同一個broker上辰斋,其二是各個分區(qū)的首領(lǐng)副本盡量不要在同一個broker上。文件管理上瘸味,Kafka不會永久保留數(shù)據(jù),會為每個主題設(shè)置數(shù)據(jù)保留期限够挂。但對于當前正在寫入的片段(活躍片段)旁仿,永遠不會被Kafka刪除。需要關(guān)注的另一點是孽糖,Kafka內(nèi)對于每條消息枯冈,都保存了一個長整型的參數(shù),也叫做偏移量办悟。Kafka為每個分區(qū)維護了一個索引尘奏,索引把偏移量映射到片段文件和偏移量在文件里的位置。

二病蛉、Kafka可靠性保證

《Kafka權(quán)威指南》一書總結(jié)了Kafka的幾點基本的可靠性保證機制:

? Kafka 可以保證分區(qū)消息的順序炫加。如果使用同一個生產(chǎn)者往同一個分區(qū)寫入消息,而且消息B 在消息A 之后寫入铺然,那么Kafka 可以保證消息B 的偏移量比消息A 的偏移量大俗孝,而且消費者會先讀取消息A 再讀取消息B 。

? 只有當消息被寫入分區(qū)的所有同步副本時(但不一定要寫入磁盤)魄健,它才被認為是“ 已提交”的赋铝。生產(chǎn)者可以選擇接收不同類型的確認,比如在消息被完全提交時的確認沽瘦,或者在消息被寫入首領(lǐng)副本時的確認革骨,或者在消息被發(fā)送到網(wǎng)絡(luò)時的確認。

? 只要還有一個副本是活躍的析恋,那么已經(jīng)提交的消息就不會丟失良哲。

??消費者只能讀取已經(jīng)提交的消息。

這些基本的保證機制可以用來構(gòu)建可靠的系統(tǒng)绿满,但僅僅依賴它們是無法保證系統(tǒng)完全可靠的臂外。構(gòu)建一個可靠的系統(tǒng)需要作出一些權(quán)衡, Kafka 管理員和開發(fā)者可以在配置參數(shù)上作出權(quán)衡喇颁,從而得到他們想要達到的可靠性漏健。

講回復(fù)制,這里延伸一個同步副本的概念橘霎。如果某個跟隨者副本的消息數(shù)據(jù)和首領(lǐng)副本能保持一致蔫浆,那么這個副本可以認為是一個同步副本。要成為一個同步副本姐叁,主要有以下三個條件:
1.跟隨者副本與zk 6s內(nèi)有保持心跳(秒數(shù)可配)
2. 10s內(nèi)從首領(lǐng)那里獲取消息(可配)
3. 在首領(lǐng)那里獲取過最新消息

broker的配置是保證良好的復(fù)制機制的主要因素瓦盛。這里有三個主要參數(shù):
1.復(fù)制系數(shù)(replication):即要有多少個跟隨者副本洗显。這里一般配3(面試題:為什么是3)。如果是1原环,broker一旦重啟服務(wù)就不可用了挠唆。如果是2,假設(shè)現(xiàn)在屬于控制器的broker重啟嘱吗,那么它會影響到分區(qū)選舉玄组,一旦另一個broker也不可用,那么分區(qū)就可能出現(xiàn)"群龍無首"的情況,導(dǎo)致重復(fù)消息或者丟失消息谒麦。另一方面俄讹,如果是舊版Kafka,1個broker失效會導(dǎo)致集群不穩(wěn)定绕德,導(dǎo)致控制器重啟患膛,也會有服務(wù)不可用的情況發(fā)生。
2.不完全的首領(lǐng)選舉(unclean.leader.election.enable)
當所有跟隨者副本因為broker宕機耻蛇,或者因為網(wǎng)絡(luò)問題導(dǎo)致數(shù)據(jù)不同步時踪蹬,這個時候只有首領(lǐng)副本的數(shù)據(jù)是全量數(shù)據(jù)。跟隨者副本重啟臣咖,這個時候如果首領(lǐng)副本掛了延曙,那么要不要讓未同步的跟隨者副本有資格成為首領(lǐng)副本呢?這個時候要根據(jù)業(yè)務(wù)場景給出選擇亡哄。參數(shù)為false枝缔,那么分區(qū)在舊首領(lǐng)(最后一個同步副本)恢復(fù)之前是不可用的。參數(shù)為true蚊惯,那么可能那么就要承擔丟失數(shù)據(jù)和出現(xiàn)數(shù)據(jù)不一致的風險愿卸。
3.最小同步副本min.insync.replicas
如果要確保已提交的數(shù)據(jù)被寫入不止一個副本,就需要把最少同步副本數(shù)量設(shè)置為大一點的值截型。對于一個包含3 個副本的主題趴荸,如果min.insync.replicas 被設(shè)為2 ,那么至少要存在兩個同步副本才能向分區(qū)寫入數(shù)據(jù)宦焦。如果這個時候只有一個同步副本发钝,那么broker就會停止接受生產(chǎn)者的請求,這個時候該分區(qū)只有只讀狀態(tài)波闹。

除了在broker的配置酝豪,生產(chǎn)者也需要進行可靠性的配置,否則也會有丟消息的風險精堕。這里主要為ack的設(shè)置孵淘,值有0、1和All歹篓,生產(chǎn)者重試次數(shù)的配置瘫证,以及當接收到Kafka服務(wù)端返回錯誤時揉阎,額外的錯誤處理方式”嘲疲可以思考兩個例子:
1.生產(chǎn)者設(shè)置ack=1毙籽,即收到首領(lǐng)副本返回的參數(shù)時認為消息已提交。一旦有消息發(fā)送到首領(lǐng)毡庆,首領(lǐng)在還沒完全同步到其他跟隨者時返回成功后惧财,發(fā)生宕機,重新選舉后選出的首領(lǐng)副本不包含這條生產(chǎn)者的消息扭仁。
2.消息被發(fā)到集群時整好發(fā)生選舉,服務(wù)端拋了一個“LeaderNotAvailableException"異常厅翔,生產(chǎn)者沒處理這類錯誤乖坠,認為消息已提交。

除了broker和生產(chǎn)者刀闷,消費者也有可靠性配置保證消息的消費熊泵。
第一個是group.id,用于標識consumerGroup甸昏。
第二個是auto.offset.reset,這個參數(shù)指定了在沒有偏移量可提交時(比如消費者第l 次啟動時)或者請求的偏移量在broker 上不存在時(第4 章已經(jīng)解釋過這種場景)顽分,消費者會做些什么。這個參數(shù)有兩種配置施蜜。一種是earliest 卒蘸,如果選擇了這種配置,消費者會從分區(qū)的開始位置讀取數(shù)據(jù)翻默,不管偏移量是否有效缸沃,這樣會導(dǎo)致消費者讀取大量的重復(fù)數(shù)據(jù),但可以保證最少的數(shù)據(jù)丟失修械。一種是latest趾牧,如果選擇了這種配置,消費者會從分區(qū)的末尾開始讀取數(shù)據(jù)肯污,這樣可以減少重復(fù)處理消息翘单,但很有可能會錯過一些消息。
第三個是自動提交的參數(shù)(enable.auto.commit和auto.commit.interval.ms),允許自動提交和自動提交的頻度(默認5秒)
如果是顯式提交蹦渣,那么就交由程序去決定什么時候提交哄芜,需要考慮一些事項,比如是否總是在處理完事件后再提交偏移量柬唯、提交頻度是性能和重復(fù)消息數(shù)量之間的權(quán)衡忠烛、再均衡等等。

三权逗、阿里面試題:使用Kafka在什么情況下會丟消息

經(jīng)過上面的鋪墊美尸,我們回過頭來重新審視這道面試題冤议,可以從三個方面(broker、生產(chǎn)者师坎、消費者)入手來回答恕酸。

broker:
1.replication不準確,如1或者2
2.unclean.leader.election.enable設(shè)為true胯陋,那么當有不同步的副本成為首領(lǐng)時蕊温,會丟消息

生產(chǎn)者:
ack=1,就會出現(xiàn)首領(lǐng)在同步好某條消息到所有副本前宕機遏乔,不包含該條消息的副本成為首領(lǐng)义矛,導(dǎo)致丟消息
ack=0,? 生產(chǎn)者不等待服務(wù)端的響應(yīng)就認為已提交所有消息,雖然收獲了客觀的吞吐量盟萨,但是保證不了消息不丟凉翻。
沒有錯誤處理機制或者重試機制,當遇到LeaderNotAvailableException異衬砑ぃ或者網(wǎng)絡(luò)異常時制轰,沒有相應(yīng)的處理方式會導(dǎo)致丟消息。

消費者:
消費者在未消費完所有消息時提交了偏移量胞谭,如果在某條消息還未消費的情況下宕機垃杖,因為服務(wù)端只認偏移量,那么會導(dǎo)致這條消息丟失丈屹。
auto.offset.reset=latest,只取最新的消息调俘,那么舊的消息有可能因為沒消費到而丟失。
消費者再均衡時發(fā)現(xiàn)提交的offset和消費到的offset不一致旺垒,加入已消費的offset在提交的offset之前脉漏,會丟消息,反之則有重復(fù)消息袖牙。

四侧巨、參考文獻:

1.《Kafka權(quán)威指南》

2.?Kafka中的消息是否會丟失和重復(fù)消費

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鞭达,隨后出現(xiàn)的幾起案子司忱,更是在濱河造成了極大的恐慌,老刑警劉巖畴蹭,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坦仍,死亡現(xiàn)場離奇詭異,居然都是意外死亡叨襟,警方通過查閱死者的電腦和手機繁扎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人梳玫,你說我怎么就攤上這事爹梁。” “怎么了提澎?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵姚垃,是天一觀的道長。 經(jīng)常有香客問我盼忌,道長积糯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任谦纱,我火速辦了婚禮看成,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘跨嘉。我一直安慰自己川慌,他們只是感情好,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布偿荷。 她就那樣靜靜地躺著,像睡著了一般唠椭。 火紅的嫁衣襯著肌膚如雪跳纳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天贪嫂,我揣著相機與錄音寺庄,去河邊找鬼。 笑死力崇,一個胖子當著我的面吹牛斗塘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播亮靴,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼馍盟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了茧吊?” 一聲冷哼從身側(cè)響起贞岭,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎搓侄,沒想到半個月后瞄桨,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡讶踪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年芯侥,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡柱查,死狀恐怖廓俭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情物赶,我是刑警寧澤白指,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站酵紫,受9級特大地震影響告嘲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奖地,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一溯街、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧渠缕,春花似錦岔霸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至臭挽,卻和暖如春捂襟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背欢峰。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工葬荷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纽帖。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓宠漩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親懊直。 傳聞我的和親對象是個殘疾皇子扒吁,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

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