Categories
程式開發

Kafka系列第7篇:你必須要知道集群內部工作原理的一些事!


前言

上篇文章講到了消息在Partition 上的存儲形式,本來準備接著來聊聊生產中的一些使用方式,想了想還有些很重要的工作組件原理沒有講清楚,比如一個Topic 由N 個Partition 組成,那麼這些Partition 是如何均勻的分佈在不同的Broker 上?再比如當一個 Broker 宕機後,其上負責讀寫請求的主 Partition 無法正常訪問,如何讓從 Partition 轉變成主 Partition 來繼續提供正常的讀寫服務?想要解決這些問題,就必須先要了解一下 Kafka 集群內部的管理機制,其中一個非常重要的控制器就是 KafkaController。本文我們就來講講 KafkaController 是如何來解決上面提到的那些問題的。

文章概覽

KafkaController 是什麼及其選舉策略。 KafkaController 監控 ZK 的目錄分佈。 Partition 分佈算法。 Partition 的狀態轉移。 Kafka 集群的負載均衡處理流程解析。

KafkaController 是什麼及其選舉策略

Kafka 集群由多台 Broker 構成,每台 Broker 都有一個 KafkaController 用於管理當前的 Broker。試想一下,如果一個集群沒有一個“領導者”,那麼誰去和“外界”(比如 ZK)溝通呢?誰去協調 Partition 應該如何分佈在集群中的不同 Broker 上呢?誰去處理 Broker 宕機後,在其 Broker 上的主 Partition 無法正常提供讀寫服務後,將對應的從 Partition 轉變成主 Partition 繼續正常對外提供服務呢?那麼由哪個 Broker 的 KafkaController 來擔當“領導者”這個角色呢?

Kafka 的設計者很聰明,Zookeeper 既然是分佈式應用協調服務,那麼乾脆就讓它來幫Kafka 集群選舉一個“領導者”出來,這個“領導者”對應的KafkaController 稱為Leader,其他的KafkaController 被稱為Follower,在同一時刻,一個Kafka 集群只能有一個Leader 和N 個Follower。

Zookeeper 是怎麼實現 KafkaController 的選主工作呢?

稍微熟悉 Zookeeper 的小伙伴應該都比較清楚,Zookeeper 是通過監控目錄(zNode)的變化,從而做出一些相應的動作。

Zookeeper 的目錄分為四種,第一種是永久的,被稱作為 Persistent;

第二種是順序且永久的,被稱作為 Persistent_Sequential;

第三種是臨時的,被稱為 Ephemeral;

第四種是順序且臨時的,被稱作為 Ephemeral_Sequential。

KafkaController 正是利用了臨時的這一特性來完成選主的,在Broker 啟動時,每個Broker 的KafkaController 都會向ZK 的 /controller 目錄寫入BrokerId,誰先寫入誰就是Leader,剩餘的KafkaController 是Follower ,當Leader 在周期內沒有向ZK 發送報告的話,則認為Leader 掛了,此時ZK 刪除臨時的 /controller 目錄,Kafka 集群中的其他KafkaController 開始新的一輪爭主操作,流程和上面一樣。下面是選 Leader 的流程圖。

Kafka系列第7篇:你必須要知道集群內部工作原理的一些事! 1

從上圖可以看出,第一次,Broker1 成功搶先在 Zookeeper 的 /controller 目錄上寫入信息,所以 Broker1 的 KafkaController 為 Leader,其他兩個為 Follower。第二次,Broker1 宕機或者下線,此時Broker2 和Broker3 檢測到,於是開始新一輪的爭搶將信息寫入Zookeeper,從圖中可以看出,Broker2 爭到了Leader,所以Broker3 是Follower 狀態。

正常情況下,上面這個流程沒有問題,但是如果在 Broker1 離線的情況下,Zookeeper 準備刪除 /controller 的臨時 node 時,系統 hang 住沒辦法刪除,改怎麼辦呢?這裡留個小疑問供大家思考。後面會用一篇文章專門來解答 Kafka 相關的問題(包括面試題哦,敬請期待)。

KafkaController 監控的 ZK 目錄分佈

KafkaController 在初始化的時候,會針對不同的 zNode 註冊各種各樣的監聽器,以便處理不同的用戶請求或者係統內部變化請求。監控 ZK 的目錄大概可以分為兩部分,分別是 /admin 目錄和 /brokers 目錄。各目錄及其對應的功能如下表所示(需要的朋友自提)。

Kafka系列第7篇:你必須要知道集群內部工作原理的一些事! 2

Partition 分佈算法

Kafka系列第7篇:你必須要知道集群內部工作原理的一些事! 3

圖解:假設集群有 3 個 Broker,Partition 因子為 2。

隨機選取 Broker 集群中的一個 Broker 節點,然後以輪詢的方式將主 Partition 均勻的分佈到不同的 Broker 上。主 Partition 分佈完成後,將從 Partition 按照 AR 組內順序以輪詢的方式將 Partition 均勻的分佈到不同的 Broker 上。

Partition 的狀態轉移

用戶針對特定的Topic 創建了相應的Partition ,但是這些Partition 不一定時刻都能夠正常工作,所有Partition 在同一時刻會對應4 個狀態中的某一個;其整個生命週期會經歷如下狀態的轉移,分別是NonExistentPartition、NewPartition、OnlinePartition、OfflinePartition,其對應的狀態轉移情況如下圖所示。

Kafka系列第7篇:你必須要知道集群內部工作原理的一些事! 4

從上圖可以看出,Partition 的狀態會由前置狀態才能夠轉移到目標狀態的,而不是胡亂轉移狀態的。

NonExistentPartition:代表沒有創建 Partition 時的狀態,也有可能是離線的 Partition 被刪除後的狀態。

NewPartition:當 Partition 被創建時,此時只有 AR(Assigned Replica),還沒有 ISR(In-Synic Replica),此時還不能接受數據的寫入和讀取。

OnlinePartition:由 NewPartition 狀態轉移為 OnlinePartition 狀態,此時 Partition 的 Leader 已經被選舉出來了,並且也有對應的 ISR 列表等。此時已經可以對外提供讀寫請求了。

OfflinePartition:當 Partition 對應的 Broker 宕機或者網絡異常等問題,由 OnlinePartition 轉移到 OfflinePartition,此時的 Partition 已經不能在對外提供讀寫服務。當 Partition 被徹底刪除後狀態就轉移成 NonExistentPartition,當網絡恢復或者 Broker 恢復後,其狀態又可以轉移到 OnlinePartition,從而繼續對外提供讀寫服務。

Kafka 集群的負載均衡處理流程解析

前面的文章講到過,Partition 有 Leader Replica 和 Preferred Replica 兩種角色,Leader Replica 負責對外提供讀寫服務 Preferred Replica 負責同步 Leader Replica 上的數據。現在集群中假設有 3 個 Broker,3 個 Partition,每個 Partition 有 3 個 Replica,當集群運行一段時候後,集群中某些 Broker 宕機,Leader Replica 進行轉移,其過程如下圖所示。

Kafka系列第7篇:你必須要知道集群內部工作原理的一些事! 5

從上圖可以看出,集群運行一段時間後,Broker1 掛掉了,在其上運行的 Partition0 對應的 Leader Replica 轉移到了 Broker2 上。假設一段時間後Broker3 也掛了,則Broker3 上的Partition3 對應的Leader Replica 也轉移到了Broker2 上,集群中只有Broker2 上的Partition 在對外提供讀寫服務,從而造成Broker2 上的服務壓力比較大,之後Broker1和Broker3 恢復後,其上只有Preferred Replica 做備份操作。

針對以上這種隨著時間的推移,集群不在像剛開始時那樣平衡,需要通過後台線程將 Leader Replica 重新分配到不同 Broker 上,從而使得讀寫服務盡量均勻的分佈在不同的節點上。

重平衡操作是由 partition-rebalance-thread 後台線程操作的,由於其優先級很低,所以只會在集群空閒的時候才會執行。集群的不平衡的評判標準是由leader.imbalance.per.broker.percentage配置決定的,當集群的不平衡度達到10%(默認)時,會觸發後台線程啟動重平衡操作,其具體執行步驟如下:

對 Partition 的 AR 列表根據 Preferred Replica 進行分組操作。遍歷 Broker,對其上的 Partition 進行處理。統計 Broker 上的 Leader Replica 和 Preferred Replica 不相等的 Partition 個數。統計 Broker 上的 Partition 個數。 Partition 個數 / 不相等的 Partition 個數,如果大於 10%,則觸發重平衡操作;反之,則不做任何處理。

總結

本文主要介紹了 Kafka 集群服務內部的一些工作機制,相信小伙伴們掌握了這部分內容後,對 Broker 服務端的工作流程有了進一步的理解,從而更好的把控整體集群服務。下篇文章我們來正式介紹一下Kafka 常用的命令行操作,敬請期待。

往期精彩推薦

一條消息如何被存儲到 Broker 上

消息發送時,網絡“偷偷”幫忙做的那點事兒

一文讀懂消費者背後的那點”貓膩”

消息是如何在服務端存儲與讀取的,你真的知道嗎?

微信公眾號搜索【z小趙】,更多系列精彩文章等你解鎖。

Kafka系列第7篇:你必須要知道集群內部工作原理的一些事! 6