本系列主要講解kafka基本設計和原理分析,分以下內容:html
當producer向leader發送數據時,能夠經過request.required.acks
參數來設置數據可靠性的級別:apache
若是要提升數據的可靠性,在設置request.required.acks=-1
的同時,也要min.insync.replicas
這個參數(能夠在broker或者topic層面進行設置)的配合,這樣才能發揮最大的功效。min.insync.replicas
這個參數設定ISR中的最小副本數是多少,默認值爲1,當且僅當request.required.acks
參數設置爲-1時,此參數才生效。若是ISR中的副本數少於min.insync.replicas
配置的數量時,客戶端會返回異常:org.apache.kafka.common.errors.NotEnoughReplicasExceptoin: Messages are rejected since there are fewer in-sync replicas than required
。編程
接下來對acks=1和-1的兩種狀況進行詳細分析。網絡
request.required.acks=1
producer發送數據到leader,leader寫本地日誌成功,返回客戶端成功;此時ISR中的副本尚未來得及拉取該消息,leader就宕機了,那麼這次發送的消息就會丟失。
併發
request.required.acks=-1
同步(Kafka默認爲同步,即producer.type=sync)的發送模式,replication.factor>=2且min.insync.replicas>=2的狀況下,不會丟失數據。分佈式
有兩種典型狀況,一種是follower徹底同步,一種的follower部分同步
acks=-1的狀況下(如無特殊說明,如下acks都表示爲參數request.required.acks),數據發送到leader, ISR的follower所有完成數據同步後,leader此時掛掉,那麼會選舉出新的leader,數據不會丟失。
高併發
acks=-1的狀況下,數據發送到leader後 ,部分ISR的副本同步,leader此時掛掉。好比follower1h和follower2都有可能變成新的leader, producer端會獲得返回異常,producer端會從新發送數據,數據可能會重複。ui
固然上圖中若是在leader crash的時候,follower2尚未同步到任何數據,並且follower2被選舉爲新的leader的話,這樣消息就不會重複。設計
HW深刻討論
考慮上圖(即acks=-1,部分ISR副本同步)中的另外一種狀況,若是在Leader掛掉的時候,follower1同步了消息4,5,follower2同步了消息4,與此同時follower2被選舉爲leader,那麼此時follower1中的多出的消息5該作如何處理呢?3d
這裏就須要HW的協同配合了。如前所述,一個partition中的ISR列表中,leader的HW是全部ISR列表裏副本中最小的那個的LEO。相似於木桶原理,水位取決於最低那塊短板。
如上圖,某個topic的某partition有三個副本,分別爲A、B、C。A做爲leader確定是LEO最高,B緊隨其後,C機器因爲配置比較低,網絡比較差,故而同步最慢。這個時候A機器宕機,這時候若是B成爲leader,假如沒有HW,在A從新恢復以後會作同步(makeFollower)操做,在宕機時log文件以後直接作追加操做,而假如B的LEO已經達到了A的LEO,會產生數據不一致的狀況,因此使用HW來避免這種狀況。
A在作同步操做的時候,先將log文件截斷到以前本身的HW的位置,即3,以後再從B中拉取消息進行同步。
若是失敗的follower恢復過來,它首先將本身的log文件截斷到上次checkpointed時刻的HW的位置,以後再從leader中同步消息。leader掛掉會從新選舉,新的leader會發送「指令」讓其他的follower截斷至自身的HW的位置而後再拉取新的消息。
當ISR中的個副本的LEO不一致時,若是此時leader掛掉,選舉新的leader時並非按照LEO的高低進行選舉,而是按照ISR中的順序選舉。
關於做者
愛編程、愛鑽研、愛分享、愛生活
關注分佈式、高併發、數據挖掘
如需捐贈,請掃碼