本文主要闡述的是Kafka可靠性相關參數中的一個,即unclean.leader.election.enable。
隨着Kafka版本的變更,有的參數消失,也有的參數被加入進來,而傳承下來的參數一般都不太會修改既定的默認值,而unclean.leader.election.enable參數卻是其中的一個反例。
從Kafka 0.11.0.0版本開始unclean.leader.election.enable參數的默認值由原來的true改爲false,這個參數背後到底意味着什麼,Kafka的設計者處於什麼原因要修改這個默認值?
參考上圖,某種狀態下,follower2副本落後leader副本很多,並且也不在leader副本和follower1副本所在的ISR(In-Sync Replicas)集合之中。
follower2副本正在努力的追趕leader副本以求迅速同步,並且能夠加入到ISR中。但是很不幸的是,此時ISR中的所有副本都突然下線,情形如下圖所示:
此時follower2副本還在,就會進行新的選舉,不過在選舉之前首先要判斷unclean.leader.election.enable參數的值。
如果unclean.leader.election.enable參數的值爲false,那麼就意味着非ISR中的副本不能夠參與選舉,此時無法進行新的選舉,此時整個分區處於不可用狀態。
如果unclean.leader.election.enable參數的值爲true,那麼可以從非ISR集合中選舉follower副本稱爲新的leader。
我們進一步考慮unclean.leader.election.enable參數爲true的情況,在上面的這種情形中follower2副本就順其自然的稱爲了新的leader。
隨着時間的推進,新的leader副本從客戶端收到了新的消息,如上圖所示。
此時,原來的leader副本恢復,成爲了新的follower副本,準備向新的leader副本同步消息,但是它發現自身的LEO比leader副本的LEO還要大。
Kafka中有一個準則,follower副本的LEO是不能夠大於leader副本的,所以新的follower副本就需要截斷日誌至leader副本的LEO處。
如上圖所示,新的follower副本需要刪除消息4和消息5,之後才能與新的leader副本進行同步。之後新的follower副本和新的leader副本組成了新的ISR集合,參考下圖。
原本客戶端已經成功的寫入了消息4和消息5,而在發生日誌截斷之後就意味着這2條消息就丟失了,並且新的follower副本和新的leader副本之間的消息也不一致。
也就是說如果unclean.leader.election.enable參數設置爲true,就有可能發生數據丟失和數據不一致的情況,Kafka的可靠性就會降低;而如果unclean.leader.election.enable參數設置爲false,Kafka的可用性就會降低。
具體怎麼選擇需要讀者更具實際的業務邏輯進行權衡,可靠性優先還是可用性優先。
從Kafka 0.11.0.0版本開始將此參數從true設置爲false,可以看出Kafka的設計者偏向於可靠性,如果能夠容忍uncleanLeaderElection場景帶來的消息丟失和不一致,可以將此參數設置爲之前的老值——true。