Kafka Partition詳解
點擊上方“IT那活兒”公眾號,關注后了解更多內容,不管IT什么活兒,干就完了!!!
Partition(分區(qū))是 Kafka 的核心角色,對于 Kafka 的存儲結構、消息的生產消費方式都至關重要。
掌握好 Partition 就可以更快的理解 Kafka。本文會講解 Partition 的概念、結構,以及行為方式。在深入 Partition 之前,我們先看幾個更高層次的概念,以及它們與 Partition 的聯(lián)系。
- Event(事件)代表過去發(fā)生的一個事實。簡單理解就是一條消息、一條記錄。Event 是不可變的,但是很活躍,經常從一個地方流向另一個地方。
- 當一個事件流進入 Kafka 之后,它就成為了一個 Topic 主題。
所以,Topic 就是具體的事件流,也可以理解為一個 Topic 就是一個靜止的 Stream。Topic 把相關的 Event 組織在一起,并且保存。一個 Topic 就像數(shù)據(jù)庫中的一張表。
Kafka 中 Topic 被分成多個 Partition 分區(qū)。Topic 是一個邏輯概念,Partition 是最小的存儲單元,掌握著一個 Topic 的部分數(shù)據(jù)。每個 Partition 都是一個多帶帶的 log 文件,每條記錄都以追加的形式寫入。Partition 中的每條記錄都會被分配一個唯一的序號,稱為 Offset(偏移量)。Offset 是一個遞增的、不可變的數(shù)字,由 Kafka 自動維護。當一條記錄寫入 Partition 的時候,它就被追加到 log 文件的末尾,并被分配一個序號,作為 Offset。如上圖,這個 Topic 有 3 個 Partition 分區(qū),向 Topic 發(fā)送消息的時候,實際上是被寫入某一個 Partition,并賦予 Offset。消息的順序性需要注意,一個 Topic 如果有多個 Partition 的話,那么從 Topic 這個層面來看,消息是無序的。但多帶帶看 Partition 的話,Partition 內部消息是有序的。所以,一個 Partition 內部消息有序,一個 Topic 跨 Partition 是無序的。如果強制要求 Topic 整體有序,就只能讓 Topic 只有一個 Partition。
Partition 為 Kafka 提供了擴展能力
一個 Kafka 集群由多個 Broker(就是 Server) 構成,每個 Broker 中含有集群的部分數(shù)據(jù)。Kafka 把 Topic 的多個 Partition 分布在多個 Broker 中。這樣會有多種好處:
- 如果把 Topic 的所有 Partition 都放在一個 Broker 上,那么這個 Topic 的可擴展性就大大降低了,會受限于這個 Broker 的 IO 能力。把 Partition 分散開之后,Topic 就可以水平擴展 。
- 一個 Topic 可以被多個 Consumer 并行消費。如果 Topic 的所有 Partition 都在一個 Broker,那么支持的 Consumer 數(shù)量就有限,而分散之后,可以支持更多的 Consumer。
- 一個 Consumer 可以有多個實例,Partition 分布在多個 Broker 的話,Consumer 的多個實例就可以連接不同的 Broker,大大提升了消息處理能力。可以讓一個 Consumer 實例負責一個 Partition,這樣消息處理既清晰又高效。
Partition 為 Kafka 提供了數(shù)據(jù)冗余
Kafka 為一個 Partition 生成多個副本,并且把它們分散在不同的 Broker。如果一個 Broker 故障了,Consumer 可以在其他 Broker 上找到 Partition 的副本,繼續(xù)獲取消息。
一個 Topic 有多個 Partition,那么,向一個 Topic 中發(fā)送消息的時候,具體是寫入哪個 Partition 呢?有3種寫入方式。方式一:使用 Partition Key 寫入特定 Partition
Producer 發(fā)送消息的時候,可以指定一個 Partition Key,這樣就可以寫入特定 Partition 了。Partition Key 可以使用任意值,例如設備ID、User ID。Partition Key 會傳遞給一個 Hash 函數(shù),由計算結果決定寫入哪個 Partition。所以,有相同 Partition Key 的消息,會被放到相同的 Partition。例如使用 User ID 作為 Partition Key,那么此 ID 的消息就都在同一個 Partition,這樣可以保證此類消息的有序性。例如使用 User ID 作為 Partition Key,如果某一個 User 產生的消息特別多,是一個頭部活躍用戶,那么此用戶的消息都進入同一個 Partition 就會產生熱點問題,導致某個 Partition 極其繁忙。方式二:kafka決定
如果沒有使用 Partition Key,Kafka 就會使用輪詢的方式來決定寫入哪個 Partition。方式三:自定義規(guī)則
Kafka 支持自定義規(guī)則,一個 Producer 可以使用自己的分區(qū)指定規(guī)則。
Kafka 不像普通消息隊列具有發(fā)布/訂閱功能,Kafka 不會向 Consumer 推送消息。Consumer 必須自己從 Topic 的 Partition 拉取消息。一個 Consumer 連接到一個 Broker 的 Partition,從中依次讀取消息。消息的 Offset 就是 Consumer 的游標,根據(jù) Offset 來記錄消息的消費情況。讀完一條消息之后,Consumer 會推進到 Partition 中的下一個 Offset,繼續(xù)讀取消息。Offset 的推進和記錄都是 Consumer 的責任,Kafka 是不管的。例如一個 Topic 有 3 個 Partition,你有 4 個 Consumer 負責這個 Topic,也只會有3個 Consumer 工作,另一個作為后補隊員,當某個 Consumer 故障了,它再補上去,是一種很好的容錯機制。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/129135.html