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

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

文章目錄

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

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

Topic 分區(qū)副本

在 Kafka 0.8.0 之前,Kafka 是沒有副本的概念的吧碾,那時候人們只會用 Kafka 存儲一些不重要的數(shù)據(jù)凰盔,因?yàn)闆]有副本,數(shù)據(jù)很可能會丟失倦春。但是隨著業(yè)務(wù)的發(fā)展户敬,支持副本的功能越來越強(qiáng)烈落剪,所以為了保證數(shù)據(jù)的可靠性,Kafka 從 0.8.0 版本開始引入了分區(qū)副本(詳情請參見 KAFKA-50)尿庐。也就是說每個分區(qū)可以人為的配置幾個副本(比如創(chuàng)建主題的時候指定 replication-factor忠怖,也可以在 Broker 級別進(jìn)行配置 default.replication.factor),一般會設(shè)置為3抄瑟。

Kafka 可以保證單個分區(qū)里的事件是有序的凡泣,分區(qū)可以在線(可用),也可以離線(不可用)皮假。在眾多的分區(qū)副本里面有一個副本是 Leader问麸,其余的副本是 follower,所有的讀寫操作都是經(jīng)過 Leader 進(jìn)行的钞翔,同時 follower 會定期地去 leader 上的復(fù)制數(shù)據(jù)严卖。當(dāng) Leader 掛了的時候,其中一個 follower 會重新成為新的 Leader布轿。通過分區(qū)副本哮笆,引入了數(shù)據(jù)冗余,同時也提供了 Kafka 的數(shù)據(jù)可靠性汰扭。

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

Producer 往 Broker 發(fā)送消息

如果我們要往 Kafka 對應(yīng)的主題發(fā)送消息萝毛,我們需要通過 Producer 完成项阴。前面我們講過 Kafka 主題對應(yīng)了多個分區(qū),每個分區(qū)下面又對應(yīng)了多個副本笆包;為了讓用戶設(shè)置數(shù)據(jù)可靠性环揽, Kafka 在 Producer 里面提供了消息確認(rèn)機(jī)制。也就是說我們可以通過配置來決定消息發(fā)送到對應(yīng)分區(qū)的幾個副本才算消息發(fā)送成功庵佣∏附海可以在定義 Producer 時通過 acks 參數(shù)指定(在 0.8.2.X 版本之前是通過 request.required.acks 參數(shù)設(shè)置的,詳見 KAFKA-3043)巴粪。這個參數(shù)支持以下三種值:

  • acks = 0:意味著如果生產(chǎn)者能夠通過網(wǎng)絡(luò)把消息發(fā)送出去通今,那么就認(rèn)為消息已成功寫入 Kafka 。在這種情況下還是有可能發(fā)生錯誤肛根,比如發(fā)送的對象無能被序列化或者網(wǎng)卡發(fā)生故障辫塌,但如果是分區(qū)離線或整個集群長時間不可用,那就不會收到任何錯誤派哲。在 acks=0 模式下的運(yùn)行速度是非尘拾保快的(這就是為什么很多基準(zhǔn)測試都是基于這個模式),你可以得到驚人的吞吐量和帶寬利用率狮辽,不過如果選擇了這種模式一也, 一定會丟失一些消息巢寡。
  • acks = 1:意味若 Leader 在收到消息并把它寫入到分區(qū)數(shù)據(jù)文件(不一定同步到磁盤上)時會返回確認(rèn)或錯誤響應(yīng)。在這個模式下椰苟,如果發(fā)生正常的 Leader 選舉抑月,生產(chǎn)者會在選舉時收到一個 LeaderNotAvailableException 異常,如果生產(chǎn)者能恰當(dāng)?shù)靥幚磉@個錯誤舆蝴,它會重試發(fā)送悄息谦絮,最終消息會安全到達(dá)新的 Leader 那里。不過在這個模式下仍然有可能丟失數(shù)據(jù)洁仗,比如消息已經(jīng)成功寫入 Leader层皱,但在消息被復(fù)制到 follower 副本之前 Leader發(fā)生崩潰。
  • acks = all(這個和 request.required.acks = -1 含義一樣):意味著 Leader 在返回確認(rèn)或錯誤響應(yīng)之前赠潦,會等待所有同步副本都收到悄息叫胖。如果和 min.insync.replicas 參數(shù)結(jié)合起來,就可以決定在返回確認(rèn)前至少有多少個副本能夠收到悄息她奥,生產(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)險鸳谜。如果需要確保消息的可靠性膝藕,必須將 producer.type 設(shè)置為 sync。

Leader 選舉

在介紹 Leader 選舉之前咐扭,讓我們先來了解一下 ISR(in-sync replicas)列表。每個分區(qū)的 leader 會維護(hù)一個 ISR 列表滑废,ISR 列表里面就是 follower 副本的 Borker 編號蝗肪,只有跟得上 Leader 的 follower 副本才能加入到 ISR 里面,這個是通過 replica.lag.time.max.ms 參數(shù)配置的蠕趁,具體可以參見 《一文了解 Kafka 的副本復(fù)制機(jī)制》薛闪。只有 ISR 里的成員才有被選為 leader 的可能。

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

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

  • producer 級別:acks=all(或者 request.required.acks=-1)袋狞,同時發(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)的呢湾蔓?


如果想及時了解Spark、Hadoop或者HBase相關(guān)的文章砌梆,歡迎關(guān)注微信公眾號:iteblog_hadoop

假設(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泛释,這個很類似于木桶原理。

這樣做的原因是還沒有被足夠多副本復(fù)制的消息被認(rèn)為是“不安全”的温算,如果 Leader 發(fā)生崩潰怜校,另一個副本成為新 Leader,那么這些消息很可能丟失了注竿。如果我們允許消費(fèi)者讀取這些消息茄茁,可能就會破壞一致性。試想巩割,一個消費(fèi)者從當(dāng)前 Leader(副本0) 讀取并處理了 Message4裙顽,這個時候 Leader 掛掉了,選舉了副本1為新的 Leader宣谈,這時候另一個消費(fèi)者再去從新的 Leader 讀取消息愈犹,發(fā)現(xiàn)這個消息其實(shí)并不存在,這就導(dǎo)致了數(shù)據(jù)不一致性問題闻丑。

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末怪得,一起剝皮案震驚了整個濱河市咱枉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌徒恋,老刑警劉巖蚕断,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異入挣,居然都是意外死亡亿乳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門径筏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來葛假,“玉大人,你說我怎么就攤上這事滋恬×难担” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵恢氯,是天一觀的道長带斑。 經(jīng)常有香客問我,道長勋拟,這世上最難降的妖魔是什么勋磕? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮敢靡,結(jié)果婚禮上挂滓,老公的妹妹穿的比我還像新娘。我一直安慰自己啸胧,他們只是感情好赶站,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吓揪,像睡著了一般亲怠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上柠辞,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天,我揣著相機(jī)與錄音主胧,去河邊找鬼叭首。 笑死习勤,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的焙格。 我是一名探鬼主播图毕,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼眷唉!你這毒婦竟也來了予颤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤冬阳,失蹤者是張志新(化名)和其女友劉穎蛤虐,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肝陪,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡驳庭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了氯窍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饲常。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖狼讨,靈堂內(nèi)的尸體忽然破棺而出贝淤,到底是詐尸還是另有隱情,我是刑警寧澤政供,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布播聪,位于F島的核電站,受9級特大地震影響鲫骗,放射性物質(zhì)發(fā)生泄漏犬耻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一执泰、第九天 我趴在偏房一處隱蔽的房頂上張望枕磁。 院中可真熱鬧,春花似錦术吝、人聲如沸计济。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沦寂。三九已至,卻和暖如春淘衙,著一層夾襖步出監(jiān)牢的瞬間传藏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留毯侦,地道東北人哭靖。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像侈离,于是被迫代替她去往敵國和親试幽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

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