掃二維碼與項(xiàng)目經(jīng)理溝通
我們在微信上24小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
這篇文章,給大家聊一下寫入Kafka的數(shù)據(jù)該如何保證其不丟失?

站在用戶的角度思考問題,與客戶深入溝通,找到建始網(wǎng)站設(shè)計(jì)與建始網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊、虛擬主機(jī)、企業(yè)郵箱。業(yè)務(wù)覆蓋建始地區(qū)。
看過之前的文章??《字節(jié)面試官: 讓你設(shè)計(jì)一個(gè)MQ每秒要抗幾十萬并發(fā),怎么做?》??的同學(xué),應(yīng)該都知道寫入Kafka的數(shù)據(jù)是會落地寫入磁盤的。
我們暫且不考慮寫磁盤的具體過程,先大致看看下面的圖,這代表了Kafka的核心架構(gòu)原理。
那么現(xiàn)在問題來了,如果每天產(chǎn)生幾十TB的數(shù)據(jù),難道都寫一臺機(jī)器的磁盤上嗎?這明顯是不靠譜的??!
所以說,這里就得考慮數(shù)據(jù)的分布式存儲了,其實(shí)關(guān)于消息中間件的分布式存儲以及高可用架構(gòu),之前的一篇文章??《程序員別死背面試八股文了,這種面試題才是未來主流。。?!??也分析過了,但是這里,我們結(jié)合Kafka的具體情況來說說。
在Kafka里面,有一個(gè)核心的概念叫做“Topic”,這個(gè)topic你就姑且認(rèn)為是一個(gè)數(shù)據(jù)集合吧。
舉個(gè)例子,如果你現(xiàn)在有一份網(wǎng)站的用戶行為數(shù)據(jù)要寫入Kafka,你可以搞一個(gè)topic叫做“user_access_log_topic”,這里寫入的都是用戶行為數(shù)據(jù)。
然后如果你要把電商網(wǎng)站的訂單數(shù)據(jù)的增刪改變更記錄寫Kafka,那可以搞一個(gè)topic叫做“order_tb_topic”,這里寫入的都是訂單表的變更記錄。
然后假如說咱們舉個(gè)例子,就說這個(gè)用戶行為topic吧,里面如果每天寫入幾十TB的數(shù)據(jù),你覺得都放一臺機(jī)器上靠譜嗎?
明顯不太靠譜,所以Kafka有一個(gè)概念叫做Partition,就是把一個(gè)topic數(shù)據(jù)集合拆分為多個(gè)數(shù)據(jù)分區(qū),你可以認(rèn)為是多個(gè)數(shù)據(jù)分片,每個(gè)Partition可以在不同的機(jī)器上,儲存部分?jǐn)?shù)據(jù)。
這樣,不就可以把一個(gè)超大的數(shù)據(jù)集合分布式存儲在多臺機(jī)器上了嗎?大家看下圖,一起來體會一下。
但是這個(gè)時(shí)候,我們又會遇到一個(gè)問題,就是萬一某臺機(jī)器宕機(jī)了,這臺機(jī)器上的那個(gè)partition管理的數(shù)據(jù)不就丟失了嗎?
所以說,我們還得做多副本冗余,每個(gè)Partition都可以搞一個(gè)副本放在別的機(jī)器上,這樣某臺機(jī)器宕機(jī),只不過是Partition其中一個(gè)副本丟失。
如果某個(gè)Partition有多副本的話,Kafka會選舉其中一個(gè)Parititon副本作為Leader,然后其他的Partition副本是Follower。
只有Leader Partition是對外提供讀寫操作的,F(xiàn)ollower Partition就是從Leader Partition同步數(shù)據(jù)。
一旦Leader Partition宕機(jī)了,就會選舉其他的Follower Partition作為新的Leader Partition對外提供讀寫服務(wù),這不就實(shí)現(xiàn)了高可用架構(gòu)了?
大家看下面的圖,看看這個(gè)過程。
現(xiàn)在我們來看看,什么情況下Kafka中寫入數(shù)據(jù)會丟失呢?
其實(shí)也很簡單,大家都知道寫入數(shù)據(jù)都是往某個(gè)Partition的Leader寫入的,然后那個(gè)Partition的Follower會從Leader同步數(shù)據(jù)。
但是萬一1條數(shù)據(jù)剛寫入Leader Partition,還沒來得及同步給Follower,此時(shí)Leader Partiton所在機(jī)器突然就宕機(jī)了呢?
大家看下圖:
如上圖,這個(gè)時(shí)候有一條數(shù)據(jù)是沒同步到Partition0的Follower上去的,然后Partition0的Leader所在機(jī)器宕機(jī)了。
此時(shí)就會選舉Partition0的Follower作為新的Leader對外提供服務(wù),然后用戶是不是就讀不到剛才寫入的那條數(shù)據(jù)了?
因?yàn)镻artition0的Follower上是沒有同步到最新的一條數(shù)據(jù)的。
這個(gè)時(shí)候就會造成數(shù)據(jù)丟失的問題。
現(xiàn)在我們先留著這個(gè)問題不說具體怎么解決,先回過頭來看一個(gè)Kafka的核心機(jī)制,就是ISR機(jī)制。
這個(gè)機(jī)制簡單來說,就是會自動給每個(gè)Partition維護(hù)一個(gè)ISR列表,這個(gè)列表里一定會有Leader,然后還會包含跟Leader保持同步的Follower。
也就是說,只要Leader的某個(gè)Follower一直跟他保持?jǐn)?shù)據(jù)同步,那么就會存在于ISR列表里。
但是如果Follower因?yàn)樽陨戆l(fā)生一些問題,導(dǎo)致不能及時(shí)的從Leader同步數(shù)據(jù)過去,那么這個(gè)Follower就會被認(rèn)為是“out-of-sync”,從ISR列表里踢出去。
所以大家先得明白這個(gè)ISR是什么,說白了,就是Kafka自動維護(hù)和監(jiān)控哪些Follower及時(shí)的跟上了Leader的數(shù)據(jù)同步。
所以如果要讓寫入Kafka的數(shù)據(jù)不丟失,你需要要求幾點(diǎn):
好!現(xiàn)在咱們來分析一下上面幾點(diǎn)要求。
第一條,必須要求至少一個(gè)Follower在ISR列表里。
那必須的啊,要是Leader沒有Follower了,或者是Follower都沒法及時(shí)同步Leader數(shù)據(jù),那么這個(gè)事兒肯定就沒法弄下去了。
第二條,每次寫入數(shù)據(jù)的時(shí)候,要求leader寫入成功以外,至少一個(gè)ISR里的Follower也寫成功。
大家看下面的圖,這個(gè)要求就是保證說,每次寫數(shù)據(jù),必須是leader和follower都寫成功了,才能算是寫成功,保證一條數(shù)據(jù)必須有兩個(gè)以上的副本。
這個(gè)時(shí)候萬一leader宕機(jī),就可以切換到那個(gè)follower上去,那么Follower上是有剛寫入的數(shù)據(jù)的,此時(shí)數(shù)據(jù)就不會丟失了。
如上圖所示,假如現(xiàn)在leader沒有follower了,或者是剛寫入leader,leader立馬就宕機(jī),還沒來得及同步給follower。
在這種情況下,寫入就會失敗,然后你就讓生產(chǎn)者不停的重試,直到kafka恢復(fù)正常滿足上述條件,才能繼續(xù)寫入。
這樣就可以讓寫入kafka的數(shù)據(jù)不丟失。
最后總結(jié)一下,其實(shí)kafka的數(shù)據(jù)丟失問題,涉及到方方面面。
譬如生產(chǎn)端的緩存問題,包括消費(fèi)端的問題,同時(shí)kafka自己內(nèi)部的底層算法和機(jī)制也可能導(dǎo)致數(shù)據(jù)丟失。
但是平時(shí)寫入數(shù)據(jù)遇到比較大的一個(gè)問題,就是leader切換時(shí)可能導(dǎo)致數(shù)據(jù)丟失。所以本文僅僅是針對這個(gè)問題說了一下生產(chǎn)環(huán)境解決這個(gè)問題的方案。

我們在微信上24小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流