kafka系列 主題和分割槽

2021-10-19 10:39:58 字數 2987 閱讀 7978

使用kafka的同學,一定會經常接觸到主題和分割槽這兩個概念,這是kafka中最核心的兩個概念了。

主題作為乙個邏輯容器,對訊息進行歸類,主題下又可以分成若干個分割槽。所以kafka的訊息可以看成是**的結構:主題-分割槽-訊息。

每個分割槽下可以存在若干個副本,副本用來進行資料備份,提公升容災能力。

分割槽可以看成是乙個只能追加寫的日誌檔案。(當然,分割槽是邏輯上的概念,日誌檔案才是物理存在的)

分割槽的作用,是提供負載均衡的能力,類似於es的分片。不同的分割槽會被分配到不同的broker節點上,這樣就可以提公升系統的吞吐量。

訊息在追加到分割槽時,會分配乙個偏移量(offset),kafka保證單分割槽的訊息有序性。

如上圖所示,假如主題分為4個分割槽,向主題寫訊息時,訊息會根據分割槽規則,順序追加到其中乙個分割槽。所以分割槽規則需要合理設定,這樣才可以讓訊息均勻到分布到不同分割槽中。

常見分割槽策略:

輪詢策略:順序分配,新產生的訊息,被順序的寫入各個分割槽。輪詢策略能夠保證訊息最大限度的被平均分配到不同分割槽。

隨機策略:訊息會被隨機寫入任意乙個分割槽。

按照key進行分割槽:我們可以為訊息定義訊息鍵,簡稱key,具有相同key的訊息,會被寫入相同的分割槽。

kafka預設的分割槽策略,同時支援按照key和輪詢。如果指定的key,則會按照key進行分割槽,如果不指定key,則會採用輪詢策略。

主題、分割槽和副本的關係:

之前也提到過,kafka的副本,是用來備份的,乙個分割槽可以存在多個副本,但只會有乙個leader副本。其餘的都是follower副本。訊息總是會寫到leader副本中,消費者也總是從leader副本中讀取訊息,follower副本只是備份的作用,follower副本會不斷的從leader副本中同步訊息。

為什麼kafka不把follower副本設計成可以提供讀服務呢?

其實kafka從**層面,是可以支援這個功能的,但是kafka並沒有這麼做,可以從副本的機制來分析下。

如果副本提供讀服務,那我們就可以做到讀寫分離,master副本只處理寫請求,follower副本處理讀請求。這解決的問題是master副本效能瓶頸問題,把讀服務分擔到follower副本。但其實kafka的分割槽機制,已經解決了這個問題了。乙個topic可以分為多個分割槽,每個分割槽都會有master副本,這些master副本會分布到不同的broker節點上,實現了負載均衡。

如果支援follower副本提供讀服務,那就需要解決讀寫分離的各種問題,比如主從延遲等,不支援follower提供讀服務,則省去了很多額外的問題處理,使得系統更容易維護。

和分割槽、副本相關的一些概念:

ar:分割槽中的所有副本統稱為ar (assigned replicas)

isr:所有與leader 副本保持一定程度同步的副本(包括leader 副本在內〕組成isr (on-sync replicas)

osr:與leader 副本同步滯後過多的副本(不包括leader 副本)組成osr (out-of-sync replicas)

從定義可以看出,ar=isr+osr。

在正常情況下, 所有的follower 副本都應該與leader 副本保持一定程度的同步,即ar=isr,osr 集合為空。

hw: 是high watermark 的縮寫,俗稱高水位,它標識了乙個特定的訊息偏移量( offset ),消費者只能拉取到這個offset 之前的訊息。分割槽高水位以下的訊息,被認為是已經提交的訊息,高水位以上的訊息被認為是未提交的訊息。高水位可以幫助kafka完成副本同步。

leo: 是log end offset 的縮寫,它標識當前日誌檔案中下一條待寫入訊息的offset。leo 的大小相當於當前日誌分割槽中最後一條訊息的offset 值加1。

上圖的這個例子,當前日誌檔案,有9條訊息,offset為0-8,下一條待寫入的訊息offset為9,也就是leo為9。此時hw為6,代表消費者只能拉取到offset為0-5之間的訊息。

高水位和 leo 是副本物件的兩個重要屬性。kafka 所有副本都有對應的高水位和 leo 值,而不僅僅是 leader 副本。只不過 leader 副本比較特殊,kafka 使用 leader 副本的高水位來定義所在分割槽的高水位。

接下來再看個稍微複雜一些的例子:

假設當前分割槽的isr集合有三個副本,乙個leader,兩個follower。每個副本當前都有三條訊息,offset為0-2,此時,該分割槽的leo和hw都是3。接下來,訊息3和訊息4,會被寫入leader副本。

訊息3和4被寫入leader副本後,此時leader副本的leo為5,hw為3。接下來,follower副本需要拉取訊息進行同步。

假如此時follower1拉取了訊息3和4,follower2只拉取了訊息3,那此時leader副本的leo為5,hw為4,follower1副本的leo為5,follower2副本的leo為4,那當前分割槽的hw為4,消費者可以消費到offset為0-3的訊息。

最終,follower1和follower2都同步了訊息3和4,此時leader副本的leo和hw都為5,follow1和follow2的leo也是5,當前分割槽的hw也是5。

參考:《深入理解kafka核心設計與實踐原理》

Kafka訂閱主題與分割槽

在建立好消費者之後,我們就需要為該消費者訂閱相關的主題了。乙個消費者可以訂閱乙個或多個主題 使用subscribe 方法訂閱了乙個主題,對於這個方法而言,既可以以集合的形式訂閱多個主題,也可以以正規表示式的形式訂閱特定模式的主題,消費者使用集合的方式 subscribe collection 來訂閱...

kafka刪除主題資料和刪除主題

1 刪除主題 在server.properties中增加設定,預設未開啟 delete.topic.enable true 刪除主題命令 bin kafka topics delete topic test zookeeper localhost 2181 2 刪除主題資料 如果想保留主題,只刪除主...

kafka 修改分割槽 kafka分割槽

一 topic下引入partition的作用 topic是邏輯的概念,partition是物理的概念。為了效能考慮,如果topic內的訊息只存於乙個broker,那這個broker會成為瓶頸,無法做到水平擴充套件。kafka通過演算法盡可能的把partition分配到集群的不同伺服器上。partit...