leader和follower
kafka的leader和follower是相對于分區有意義的,不是相對于broker。
因為每個分區都有leader和follower,
leader負責讀寫數據。
follower負責復制leader的數據保存到自己的日志數據中,并在leader掛掉后重新選舉出leader。
kafka會再創建topic的時候盡量讓分配分區的leader在不同的broker中,就是負載均衡。
與Zookeeper區分
zookeeper的leader負責讀寫,follower可以讀取。
kafka的leader負責讀寫,follower不能讀寫數據(確保每個消費者消費的數據是一致的),kafka一個topic有多個分區leader,一樣可以實現負載均衡。
AR/ISR/OSR
kafka的follower可以分為三類:AR ISR OSR
- AR(Assigned Replicas)表示一個topic下的所有副本。
- ISR(In-Sync Replicas)表示一個topic下正在同步的副本。
- OSR表示(OUT-SYNC-Replicas)不再同步的副本。
AR=ISR+OSR
查看分區的ISR
使用Kafka Eagle查看某個Topic的partition的ISR有哪幾個節點。
partition是創建的topic為test的? 0 1 2 三個分區。
Log Size是日志文件的大小
Leader是leader副本在那個broker節點上
Replicas是它的副本在哪些broker節點上。
In sync Replicas是正在同步的副本(包括leader)
嘗試關閉id為0的broker(殺掉該broker的進程),參看topic的ISR情況。
leader的選舉
leader的選舉對于消息的寫入以及讀取非常關鍵,此時有兩個疑問:
- kafka是如何確定partition的哪個副本是leader,那個副本是follower呢?
- 某個leader崩潰后,怎么快速確定另一個leader呢?因為Kafka的吞吐量很高、延遲很低,所以選舉leader必須非常快
leader崩潰,kafka如果處理
使用Kafka Eagle找到某個partition的leader,再找到leader所在的broker。在Linux中強制殺掉該Kafka的進程,然后觀察leader的情況。
通過觀察,我們發現,leader在崩潰后,Kafka又從其他的follower中快速選舉出來了leader。
Controller
- kafka啟動的時候,會在所有的broker中選舉出controller
- 前面的leader和follower是針對partition的副本,而controller是針對broker的。
- 創建topic或者添加分區,修改副本數量之類的管理任務都是交給controller完成的。
- kafka分區leader的選舉,也是由controller決定的。
Controller的選舉
- 在kafka集群啟動的時候,每個broker都會嘗試去Zookeeper上注冊為controller(ZK臨時節點)
- 但是只有一個競爭成功,其他的broker會注冊該節點的監視器。
- 一但節點的狀態發生變化,就可以進行處理。
- Controller也是高可用的,一旦某個broker崩潰,其他的broker會重新注冊為Controller。
Controller選舉partition的leader
- 所有Partition的leader選舉都由controller決定.
- controller會將leader的改變通過RPC的方式通知需要為此做出響應的Broker
- controller讀取當前分區的ISR,只要有一個Replica還幸存,就選擇其中一個作為leader。
- 如果該partition的所有Replica都已經宕機,則新的leader為-1
為什么不通過ZK的方式進行選舉?
如果kafka是居于ZK進行選舉,ZK的壓力比較大,例如某個節點崩潰,這個節點上不僅僅只有一個leader,是有不少的leader需要選舉,通過ISR可以快速選舉。
leader的負載均衡
kafka中引入Preferred Replica的概念,意思是優先的Replica。
在ISR中第一個replica就是preferred-replica.
副本存放的第一個broker,肯定就是preferred-replica
執行以下腳本可以將preferred-replica設置為leader,均勻分配每個分區的leader。
./kafka-leader-election.sh --bootstrap-server node1.itcast.cn:9092 --topic 主題 --partition=1 --election-type preferred