3、kafka消息可靠性

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

當(dāng)producer發(fā)送消息給kafka集群,如何保證數(shù)據(jù)發(fā)送過去了呢? 這就需要kafka集群在收到消息時給producer一個反饋, 當(dāng)producer收到這個反饋就說明消息發(fā)送成功, 如果沒有收到就反饋,就說明消息發(fā)送失敗,需要重發(fā)!

kafka 集群發(fā)送的這個反饋稱為ack,但是什么時機(jī)發(fā)送這個ack呢? 這個ack的發(fā)送機(jī)制有以下3種情況:

  1. 當(dāng)消息發(fā)送給某個partition的leader,當(dāng)這個leader收到這個消息,就直接發(fā)送ack;
  2. 當(dāng)消息發(fā)送給某個partition的leader,然后等它的全部follower都從leader那里同步完獲取消息后,再發(fā)送ack;
  3. 當(dāng)消息發(fā)送給某個partition的leader,然后等它的其中一部分follower從leader那里同步獲取完消息后,就發(fā)送ack;

3種方式各有各的好處與優(yōu)缺點:
第1種:是光leader收到消息,萬一follower沒收到消息,然后leader掛了,數(shù)據(jù)丟失了; 但好處是延遲低;
第2種:是當(dāng)全部的follower都收到消息再發(fā)ack,這個消息是有了,但是延遲高;
第3種:這中方式也是kafka采用的方式, 當(dāng)leader收到消息后,再等其中一部分follower同步獲取完消息,那么就發(fā)送ack; 這樣也算是一種折中的辦法; 但問題是,這里的其中一部分follower該怎么確定呢? 于是就有了ISR,ISR機(jī)制被成為“不丟消息”機(jī)制; ISR的邏輯就是:從全部的follower中根據(jù)某個配置規(guī)則選出一些來,例如和leader通信較好的,或者同步數(shù)據(jù)比較快(數(shù)據(jù)同步時與leader的數(shù)據(jù)差距最小), 這樣選出一些follower來,當(dāng)這些follower同步獲取完到消息后,就直接發(fā)送ack; 但是follower的情況是在變化的, 有時候某臺follower有問題了(掛了或卡了或延遲太久), 例如和leader 的通信斷掉了,或者同步消息進(jìn)行的很慢(與leader的數(shù)據(jù)差距較大),這樣的follower就踢出ISR的隊列;

總結(jié): kafka用一種比較折中的算法,用ISR算法,既保證了數(shù)據(jù)的可靠性,又降低了kafka的延遲;

ps: 選取某些follower時,是根據(jù)以下這兩個配置規(guī)則來的:
replica.log.max.messages 默認(rèn)值是10000條消息;
replica.log.time.max.ms 默認(rèn)值是10000毫秒;
當(dāng)follower有了延遲,與leader 的數(shù)據(jù)量同步差距擴(kuò)大的10000條消息記錄時,該follower就被踢出ISR;
當(dāng)follower與leader的心跳消息超過10秒,說明該節(jié)點有可能是掛掉了,該follower就被踢出ISR;
注:在新的版本中,replica.log.max.messages 配置已經(jīng)被removed了,不再考慮這個配置了;只保留了rerplica.lag.time.max.ms設(shè)置;

本文關(guān)鍵點:

  1. topic下的每個partition都有副本,其中一個是leader,其他的是follower;
  2. follower是主動從leader那里fetch(獲取)數(shù)據(jù);
  3. leader都會維持一個與其保持同步的replica集合,該集合就是ISR;
  4. 我們要保證kafka不丟失message,就要保證ISR這組集合存活(至少有一個存活),并且消息commit成功。
  5. ISR隊列是動態(tài)的,隨時在變的;

對于某些不太重要的數(shù)據(jù),對數(shù)據(jù)的可靠性要求不高,允許丟失某些數(shù)據(jù),所以沒必要完全等ISR隊列的follower全部接受完數(shù)據(jù)才發(fā)ack; 所以kafka為我們提供了3種級別的可靠性, 可以根據(jù)實際情況進(jìn)行配置:
ack = 0,producer只管發(fā)數(shù)據(jù),不等消息是否真正寫成功;
ack = 1, producer等leader接受成功就行了,如果leader故障,會導(dǎo)致數(shù)據(jù)丟失;
ack= -1,producer等leader和follower全部都接受成功后才返回ack,但是如果當(dāng)消息都發(fā)送成功,卻恰好在此時leader掛了, 也就沒法給producer發(fā)送反饋ack了, 然后producer會認(rèn)為數(shù)據(jù)發(fā)送失敗(實際卻是成功了的),導(dǎo)致數(shù)據(jù)重復(fù);

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

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

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