Kafka 是如何保證數(shù)據(jù)可靠性和一致性

學(xué)過大數(shù)據(jù)的同學(xué)應(yīng)該都知道 Kafka凉翻,它是分布式消息訂閱系統(tǒng),有非常好的橫向擴(kuò)展性制轰,可實(shí)時(shí)存儲海量數(shù)據(jù),是流數(shù)據(jù)處理中間件的事實(shí)標(biāo)準(zhǔn)垃杖。本文將介紹 Kafka 是如何保證數(shù)據(jù)可靠性和一致性的男杈。

數(shù)據(jù)可靠性

Kafka 作為一個(gè)商業(yè)級消息中間件调俘,消息可靠性的重要性可想而知。本文從 Producter 往 Broker 發(fā)送消息彩库、Topic 分區(qū)副本以及 Leader 選舉幾個(gè)角度介紹數(shù)據(jù)的可靠性肤无。

Topic 分區(qū)副本

在 Kafka 0.8.0 之前骇钦,Kafka 是沒有副本的概念的,那時(shí)候人們只會用 Kafka 存儲一些不重要的數(shù)據(jù)司忱,因?yàn)闆]有副本皇忿,數(shù)據(jù)很可能會丟失坦仍。但是隨著業(yè)務(wù)的發(fā)展,支持副本的功能越來越強(qiáng)烈繁扎,所以為了保證數(shù)據(jù)的可靠性,Kafka 從 0.8.0 版本開始引入了分區(qū)副本(詳情請參見 KAFKA-50)梳玫。也就是說每個(gè)分區(qū)可以人為的配置幾個(gè)副本(比如創(chuàng)建主題的時(shí)候指定 replication-factor爹梁,也可以在 Broker 級別進(jìn)行配置 default.replication.factor)提澎,一般會設(shè)置為3姚垃。

Kafka 可以保證單個(gè)分區(qū)里的事件是有序的盼忌,分區(qū)可以在線(可用)积糯,也可以離線(不可用)谦纱。在眾多的分區(qū)副本里面有一個(gè)副本是 Leader看成,其余的副本是 follower,所有的讀寫操作都是經(jīng)過 Leader 進(jìn)行的跨嘉,同時(shí) follower 會定期地去 leader 上的復(fù)制數(shù)據(jù)。當(dāng) Leader 掛了的時(shí)候祠乃,其中一個(gè) follower 會重新成為新的 Leader梦重。通過分區(qū)副本亮瓷,引入了數(shù)據(jù)冗余琴拧,同時(shí)也提供了 Kafka 的數(shù)據(jù)可靠性寺庄。

Kafka 的分區(qū)多副本架構(gòu)是 Kafka 可靠性保證的核心,把消息寫入多個(gè)副本可以使 Kafka 在發(fā)生崩潰時(shí)仍能保證消息的持久性斗塘。

Producer 往 Broker 發(fā)送消息

如果我們要往 Kafka 對應(yīng)的主題發(fā)送消息,我們需要通過 Producer 完成馍盟。前面我們講過 Kafka 主題對應(yīng)了多個(gè)分區(qū)于置,每個(gè)分區(qū)下面又對應(yīng)了多個(gè)副本贞岭;為了讓用戶設(shè)置數(shù)據(jù)可靠性, Kafka 在 Producer 里面提供了消息確認(rèn)機(jī)制瞄桨。也就是說我們可以通過配置來決定消息發(fā)送到對應(yīng)分區(qū)的幾個(gè)副本才算消息發(fā)送成功话速⌒窘模可以在定義 Producer 時(shí)通過 acks 參數(shù)指定(在 0.8.2.X 版本之前是通過 request.required.acks 參數(shù)設(shè)置的乳讥,詳見 KAFKA-3043)。這個(gè)參數(shù)支持以下三種值:

acks = 0:意味著如果生產(chǎn)者能夠通過網(wǎng)絡(luò)把消息發(fā)送出去廓俭,那么就認(rèn)為消息已成功寫入 Kafka 。在這種情況下還是有可能發(fā)生錯(cuò)誤研乒,比如發(fā)送的對象無能被序列化或者網(wǎng)卡發(fā)生故障,但如果是分區(qū)離線或整個(gè)集群長時(shí)間不可用雹熬,那就不會收到任何錯(cuò)誤。在 acks=0 模式下的運(yùn)行速度是非抽匣#快的(這就是為什么很多基準(zhǔn)測試都是基于這個(gè)模式),你可以得到驚人的吞吐量和帶寬利用率仰楚,不過如果選擇了這種模式, 一定會丟失一些消息僧界。

acks = 1:意味若 Leader 在收到消息并把它寫入到分區(qū)數(shù)據(jù)文件(不一定同步到磁盤上)時(shí)會返回確認(rèn)或錯(cuò)誤響應(yīng)。在這個(gè)模式下捂襟,如果發(fā)生正常的 Leader 選舉咬腕,生產(chǎn)者會在選舉時(shí)收到一個(gè) LeaderNotAvailableException 異常葬荷,如果生產(chǎn)者能恰當(dāng)?shù)靥幚磉@個(gè)錯(cuò)誤涨共,它會重試發(fā)送悄息宠漩,最終消息會安全到達(dá)新的 Leader 那里举反。不過在這個(gè)模式下仍然有可能丟失數(shù)據(jù)扒吁,比如消息已經(jīng)成功寫入 Leader,但在消息被復(fù)制到 follower 副本之前 Leader發(fā)生崩潰雕崩。

acks = all(這個(gè)和 request.required.acks = -1 含義一樣):意味著 Leader 在返回確認(rèn)或錯(cuò)誤響應(yīng)之前魁索,會等待所有同步副本都收到悄息盼铁。如果和 min.insync.replicas 參數(shù)結(jié)合起來,就可以決定在返回確認(rèn)前至少有多少個(gè)副本能夠收到悄息饶火,生產(chǎn)者會一直重試直到消息被成功提交冬念。不過這也是最慢的做法趁窃,因?yàn)樯a(chǎn)者在繼續(xù)發(fā)送其他消息之前需要等待所有副本都收到當(dāng)前的消息。

根據(jù)實(shí)際的應(yīng)用場景醒陆,我們設(shè)置不同的 acks,以此保證數(shù)據(jù)的可靠性刨摩。

另外寺晌,Producer 發(fā)送消息還可以選擇同步(默認(rèn)澡刹,通過 producer.type=sync 配置) 或者異步(producer.type=async)模式。如果設(shè)置成異步罢浇,雖然會極大的提高消息發(fā)送的性能陆赋,但是這樣會增加丟失數(shù)據(jù)的風(fēng)險(xiǎn)嚷闭。如果需要確保消息的可靠性,必須將 producer.type 設(shè)置為 sync胞锰。

Leader 選舉

在介紹 Leader 選舉之前灾锯,讓我們先來了解一下 ISR(in-sync replicas)列表嗅榕。每個(gè)分區(qū)的 leader 會維護(hù)一個(gè) ISR 列表,ISR 列表里面就是 follower 副本的 Borker 編號凌那,只有跟得上 Leader 的 follower 副本才能加入到 ISR 里面兼雄,這個(gè)是通過 replica.lag.time.max.ms 參數(shù)配置的案怯。只有 ISR 里的成員才有被選為 leader 的可能。

所以當(dāng) Leader 掛掉了嘲碱,而且 unclean.leader.election.enable=false 的情況下,Kafka 會從 ISR 列表中選擇第一個(gè) follower 作為新的 Leader麦锯,因?yàn)檫@個(gè)分區(qū)擁有最新的已經(jīng) committed 的消息恕稠。通過這個(gè)可以保證已經(jīng) committed 的消息的數(shù)據(jù)可靠性扶欣。

綜上所述鹅巍,為了保證數(shù)據(jù)的可靠性,我們最少需要配置一下幾個(gè)參數(shù):

producer 級別:acks=all(或者 request.required.acks=-1)骆捧,同時(shí)發(fā)生模式為同步 producer.type=sync

topic 級別:設(shè)置 replication.factor>=3,并且 min.insync.replicas>=2敛苇;

broker 級別:關(guān)閉不完全的 Leader 選舉,即 unclean.leader.election.enable=false枫攀;

數(shù)據(jù)一致性

這里介紹的數(shù)據(jù)一致性主要是說不論是老的 Leader 還是新選舉的 Leader,Consumer 都能讀到一樣的數(shù)據(jù)来涨。那么 Kafka 是如何實(shí)現(xiàn)的呢?

假設(shè)分區(qū)的副本為3蹦掐,其中副本0是 Leader,副本1和副本2是 follower笤闯,并且在 ISR 列表里面。雖然副本0已經(jīng)寫入了 Message4颗味,但是 Consumer 只能讀取到 Message2超陆。因?yàn)樗械?ISR 都同步了 Message2浦马,只有 High Water Mark 以上的消息才支持 Consumer 讀取时呀,而 High Water Mark 取決于 ISR 列表里面偏移量最小的分區(qū)晶默,對應(yīng)于上圖的副本2,這個(gè)很類似于木桶原理磺陡。

這樣做的原因是還沒有被足夠多副本復(fù)制的消息被認(rèn)為是“不安全”的趴梢,如果 Leader 發(fā)生崩潰币他,另一個(gè)副本成為新 Leader,那么這些消息很可能丟失了蝴悉。如果我們允許消費(fèi)者讀取這些消息彰阴,可能就會破壞一致性拍冠。試想簇抵,一個(gè)消費(fèi)者從當(dāng)前 Leader(副本0) 讀取并處理了 Message4,這個(gè)時(shí)候 Leader 掛掉了射众,選舉了副本1為新的 Leader,這時(shí)候另一個(gè)消費(fèi)者再去從新的 Leader 讀取消息责球,發(fā)現(xiàn)這個(gè)消息其實(shí)并不存在,這就導(dǎo)致了數(shù)據(jù)不一致性問題雏逾。

當(dāng)然郑临,引入了 High Water Mark 機(jī)制栖博,會導(dǎo)致 Broker 間的消息復(fù)制因?yàn)槟承┰蜃兟岫矗敲聪⒌竭_(dá)消費(fèi)者的時(shí)間也會隨之變長(因?yàn)槲覀儠鹊却?fù)制完畢)仇让。延遲時(shí)間可以通過參數(shù) replica.lag.time.max.ms 參數(shù)配置躺翻,它指定了副本在復(fù)制消息時(shí)可被允許的最大延遲時(shí)間。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末公你,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子陕靠,更是在濱河造成了極大的恐慌迂尝,老刑警劉巖剪芥,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異税肪,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)益兄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來偏塞,“玉大人,你說我怎么就攤上這事灸叼∩裥冢” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵屁魏,是天一觀的道長。 經(jīng)常有香客問我氓拼,道長,這世上最難降的妖魔是什么桃漾? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮撬统,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恋追。我一直安慰自己,他們只是感情好苦囱,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著撕彤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪喉刘。 梳的紋絲不亂的頭發(fā)上瞧柔,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天睦裳,我揣著相機(jī)與錄音,去河邊找鬼廉邑。 笑死哥蔚,一個(gè)胖子當(dāng)著我的面吹牛蛛蒙,可吹牛的內(nèi)容都是我干的糙箍。 我是一名探鬼主播牵祟,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了咕晋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤掌呜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后质蕉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡模暗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汰蓉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡顾孽,死狀恐怖比规,靈堂內(nèi)的尸體忽然破棺而出若厚,到底是詐尸還是另有隱情蜒什,我是刑警寧澤测秸,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布灾常,位于F島的核電站霎冯,受9級特大地震影響钞瀑,放射性物質(zhì)發(fā)生泄漏沈撞。R本人自食惡果不足惜雕什,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望贷岸。 院中可真熱鬧壹士,春花似錦偿警、人聲如沸躏救。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至忠怖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間凡泣,已是汗流浹背枉疼。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工鞋拟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留骂维,地道東北人贺纲。 一個(gè)月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像猴誊,于是被迫代替她去往敵國和親潦刃。 傳聞我的和親對象是個(gè)殘疾皇子懈叹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

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