爲了保證producer的消息能可靠的投遞到指定的topic,topic的每一個分區partition收到消息後,都須要向producer發送ack(acknowlege確認收到),若是生產者producer收到了ack,則進行下一輪的發送,不然從新發送。ide
ACK機制的實現
問題:分區中現有一個leader副本節點和多個follower副本節點,生產者將消息發送過來的時候,什麼時候返回ack給生產者?3d
leader副本負責讀與寫,follower副本同步leader的數據。日誌
方案1:leader和全部的follower都同步完成,才發送ack給生產者
方案2:leader+follower同步完成的數量過半,就發送ack給生產者blog
kafka採用的eader+follower徹底同步機制(ISR中follower),全部節點同步完成才返回ack。kafka
存在問題:leader+follower徹底同步時,假若有1個leader+4個follower,1個leader和3個follower都同步完成,1個follower同步超級慢或者掛掉,會影響返回或者不返回ack。同步
ISR機制的實現it
當leader掛掉的時候,由controller會在follower副本中選舉出一個leader。可是這個剩餘follower副本有一個條件,就是follower必須在ISR列表中。io
leader和ISR中的follower副本都同步完成時,就返回ack。class
ISR (IN-SYNC Replication) 維護了與leader信息一致的follower副本的信息,當leader掛掉的時候 就從這個ISR中選舉。zookeeper
ISR信息存放在zookeeper的topic信息中,由kafka動態維護
leader如何動態維護ISR?
在0.9以後的版本中已經移除。
存在問題,生產者批量產生多餘4000條的消息,發送給leader,此時ISR中全部的follower副本所有落後於leader,都會被剔除ISR。而後又要有新的follower副本加入ISR(問題:頻繁操做ISR,還要操做zookeeper)。
生產者生產消息進行投遞——>分區中的leader——>通知到ISR中全部的follower副本進行同步數據——>ISR中全部的follower告知leader同步完成——>leader返回ack——>生產者
[x] acks 生產者投遞消息的ACK的級別設置
若是須要等到ISR全部的follower副本返回消息leader,可能須要等待,便產生了不一樣的ack可靠性級別
優勢:延遲性最低
缺點:若是接收到消息後leader沒有寫入磁盤就掛掉,從ISR中的follower新選舉leader後,會丟失數據。
問題:leader寫入磁盤完成後掛掉了,ISR中的follower尚未來得及同步。從ISR中的follower新選舉leader後,會丟失數據。
消費者投遞消息後,等待leader和ISR中全部的follower副本同步完成,leader才返回ack。
優勢:leader和ISR中全部的follower都同步完成,不丟數據,達到副本數據一致性。
問題:leader在返回ack以前就掛掉了,會從ISR中的follower中選出leader,此時全部leader+follower數據都一致。生產者沒有收到leader的ack迴應會重試投遞,會形成數據重複。
log中每一個消息都會有對應一個offset偏移量。
leader與ISR中全部的follower的文件的最小LEO爲HW。如上圖所示,HW爲12。
對於消費者來講,leader中不大與HW的數據才能被consumer可見。如圖所示leader文件中的0~12能夠被消費者所見。
leader選舉機制的實現
圖示HW爲9,消費者只能看到0~9
假如leader掛掉了,選舉follower2爲leader,那麼以新leader通知其餘節點以HW 9爲基準,超過HW的部分須要截取掉,leader自身的(LEO爲11 大於HW 9)不用截取掉。而後重新的leader開始同步。
**