Kafka學習之Kafka選舉機制簡述


  Kafka是一個高性能,高容錯,多副本,可復制的分布式消息系統。在整個系統中,涉及到多處選舉機制,被不少人搞混,這里總結一下,本篇文章大概會從三個方面來講解。

  • 控制器(Broker)選主
  • 分區多副本選主
  • 消費組選主

1、控制器(Broker)選舉

  所謂控制器就是一個Borker,在一個kafka集群中,有多個broker節點,但是它們之間需要選舉出一個leader,其他的broker充當follower角色。集群中第一個啟動的broker會通過在zookeeper中創建臨時節點/controller來讓自己成為控制器,其他broker啟動時也會在zookeeper中創建臨時節點,但是發現節點已經存在,所以它們會收到一個異常,意識到控制器已經存在,那么就會在zookeeper中創建watch對象,便於它們收到控制器變更的通知。

  那么如果控制器由於網絡原因與zookeeper斷開連接或者異常退出,那么其他broker通過watch收到控制器變更的通知,就會去嘗試創建臨時節點/controller,如果有一個broker創建成功,那么其他broker就會收到創建異常通知,也就意味着集群中已經有了控制器,其他broker只需創建watch對象即可。

  如果集群中有一個broker發生異常退出了,那么控制器就會檢查這個broker是否有分區的副本leader,如果有那么這個分區就需要一個新的leader,此時控制器就會去遍歷其他副本,決定哪一個成為新的leader,同時更新分區的ISR集合。

  如果有一個broker加入集群中,那么控制器就會通過Broker ID去判斷新加入的broker中是否含有現有分區的副本,如果有,就會從分區副本中去同步數據。

  集群中每選舉一次控制器,就會通過zookeeper創建一個controller epoch,每一個選舉都會創建一個更大,包含最新信息的epoch,如果有broker收到比這個epoch舊的數據,就會忽略它們,kafka也通過這個epoch來防止集群產生“腦裂”。

2、分區副本選舉機制

在kafka的集群中,會存在着多個主題topic,在每一個topic中,又被划分為多個partition,為了防止數據不丟失,每一個partition又有多個副本,在整個集群中,總共有三種副本角色:

  • leader副本:也就是leader主副本,每個分區都有一個leader副本,為了保證數據一致性,所有的生產者與消費者的請求都會經過該副本來處理。
  • follower副本:除了首領副本外的其他所有副本都是follower副本,follower副本不處理來自客戶端的任何請求,只負責從leader副本同步數據,保證與首領保持一致。如果leader副本發生崩潰,就會從這其中選舉出一個leader。
  • 優先副本:創建分區時指定的優先leader。如果不指定,則為分區的第一個副本。

  follower需要從leader中同步數據,但是由於網絡或者其他原因,導致數據阻塞,出現不一致的情況,為了避免這種情況,follower會向leader發送請求信息,這些請求信息中包含了follower需要數據的偏移量offset,而且這些offset是有序的。

  如果有follower向leader發送了請求1,接着發送請求2,請求3,那么再發送請求4,這時就意味着follower已經同步了前三條數據,否則不會發送請求4。leader通過跟蹤 每一個follower的offset來判斷它們的復制進度。

  默認的,如果follower與leader之間超過10s內沒有發送請求,或者說沒有收到請求數據,此時該follower就會被認為“不同步副本”。而持續請求的副本就是“同步副本”,當leader發生故障時,只有“同步副本”才可以被選舉為leader。其中的請求超時時間可以通過參數replica.lag.time.max.ms參數來配置。

  我們希望每個分區的leader可以分布到不同的broker中,盡可能的達到負載均衡,所以會有一個優先leader,如果我們設置參數auto.leader.rebalance.enable為true,那么它會檢查優先leader是否是真正的leader,如果不是,則會觸發選舉,讓優先leader成為leader。

3、消費組選主

  在kafka的消費端,會有一個消費者協調器以及消費組,組協調器GroupCoordinator需要為消費組內的消費者選舉出一個消費組的leader,那么如何選舉的呢?

如果消費組內還沒有leader,那么第一個加入消費組的消費者即為消費組的leader,如果某一個時刻leader消費者由於某些原因退出了消費組,那么就會重新選舉leader,如何選舉?

private val members = new mutable.HashMap[String, MemberMetadata]
leaderId = members.keys.headOption

  上面代碼是kafka源碼中的部分代碼,member是一個hashmap的數據結構,key為消費者的member_id,value是元數據信息,那么它會將leaderId選舉為Hashmap中的第一個鍵值對,它和隨機基本沒啥區別。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM