kafka資料可靠性詳解
一、AR
在Kafka中維護了一個AR列表,包括所有的分割槽的副本。AR又分為ISR和OSR。
AR = ISR + OSR。
AR、ISR、OSR、LEO、HW這些資訊都被儲存在Zookeeper中。
1.ISR
ISR中的副本都要同步leader中的資料,只有都同步完成了資料才認為是成功提交了,成功提交之後才能供外界訪問。
在這個同步的過程中,資料即使已經寫入也不能被外界訪問,這個過程是通過LEO-HW機制來實現的。
2.OSR
OSR內的副本是否同步了leader的資料,不影響資料的提交,OSR內的follower盡力的去同步leader,可能資料版本會落後。
最開始所有的副本都在ISR中,在kafka工作的過程中,如果某個副本同步速度慢於replica.lag.time.max.ms指定的閾值,則被踢出ISR存入OSR,如果後續速度恢復可以回到ISR中。
3.LEO
LogEndOffset:分割槽的最新的資料的offset,當資料寫入leader後,LEO就立即執行該最新資料。相當於最新資料標識位。
4.HW
HighWatermark:只有寫入的資料被同步到所有的ISR中的副本後,資料才認為已提交,HW更新到該位置,HW之前的資料才可以被消費者訪問,保證沒有同步完成的資料不會被消費者訪問到。相當於所有副本同步資料標識位。
在leader宕機後,只能從ISR列表中選取新的leader,無論ISR中哪個副本被選為新的leader,它都知道HW之前的資料,可以保證在切換了leader後,消費者可以繼續看到HW之前已經提交的資料。
所以LEO代表已經寫入的最新資料位置,而HW表示已經同步完成的資料,只有HW之前的資料才能被外界訪問。
5.HW截斷機制
如果leader宕機,選出了新的leader,而新的leader並不能保證已經完全同步了之前leader的所有資料,只能保證HW之前的資料是同步過的,此時所有的follower都要將資料截斷到HW的位置,再和新的leader同步資料,來保證資料一致。
當宕機的leader恢復,發現新的leader中的資料和自己持有的資料不一致,此時宕機的leader會將自己的資料截斷到宕機之前的hw位置,然後同步新leader的資料。宕機的leader活過來也像follower一樣同步資料,來保證資料的一致性。
二、生產者可靠性級別
通過以上的講解,已經可以保證kafka叢集內部的可靠性,但是在生產者向kafka叢集傳送時,資料經過網路傳輸,也是不可靠的,可能因為網路延遲、閃斷等原因造成資料的丟失。
kafka為生產者提供瞭如下的三種可靠性級別,通過不同策略保證不同的可靠性保障。
其實此策略配置的就是leader將成功接收訊息資訊響應給客戶端的時機。
通過request.required.acks引數配置:
1:生產者傳送資料給leader,leader收到資料後傳送成功資訊,生產者收到後認為傳送資料成功,如果一直收不到成功訊息,則生產者認為傳送資料失敗會自動重發資料。
當leader宕機時,可能丟失資料。
0:生產者不停向leader傳送資料,而不需要leader反饋成功訊息。
這種模式效率最高,可靠性最低。可能在傳送過程中丟失資料,也可能在leader宕機時丟失資料。
-1:生產者傳送資料給leader,leader收到資料後要等到ISR列表中的所有副本都同步資料完成後,才向生產者傳送成功訊息,如果一隻收不到成功訊息,則認為傳送資料失敗會自動重發資料。
這種模式下可靠性很高,但是當ISR列表中只剩下leader時,當leader宕機讓然有可能丟資料。
此時可以配置min.insync.replicas指定要求觀察ISR中至少要有指定數量的副本,預設該值為1,需要改為大於等於2的值
這樣當生產者傳送資料給leader但是發現ISR中只有leader自己時,會收到異常表明資料寫入失敗,此時無法寫入資料,保證了資料絕對不丟。
雖然不丟但是可能會產生冗餘資料,例如生產者傳送資料給leader,leader同步資料給ISR中的follower,同步到一半leader宕機,此時選出新的leader,可能具有部分此次提交的資料,而生產者收到失敗訊息重發資料,新的leader接受資料則資料重複了。
三、leader選舉
當leader宕機時會選擇ISR中的一個follower成為新的leader,如果ISR中的所有副本都宕機,怎麼辦?
有如下配置可以解決此問題:
unclean.leader.election.enable=false
策略1:必須等待ISR列表中的副本活過來才選擇其成為leader繼續工作。
unclean.leader.election.enable=true
策略2:選擇任何一個活過來的副本,成為leader繼續工作,此follower可能不在ISR中。
策略1,可靠性有保證,但是可用性低,只有最後掛了leader活過來kafka才能恢復。
策略2,可用性高,可靠性沒有保證,任何一個副本活過來就可以繼續工作,但是有可能存在資料不一致的情況。
四、kafka可靠性的保證
At most once:訊息可能會丟,但絕不會重複傳輸。
At least once:訊息絕不會丟,但可能會重複傳輸。
Exactly once:每條訊息肯定會被傳輸一次且僅傳輸一次。
kafka最多保證At least once,可以保證不丟,但是可能會重複,為了解決重複需要引入唯一標識和去重機制,kafka提供了GUID實現了唯一標識,但是並沒有提供自帶的去重機制,需要開發人員基於業務規則自己去重。