基本概念
Apache Kafka是一個基於publish-subscribe模型的高吞吐、低延遲、高容錯的分佈式流平臺。
kafka中常見概念:
- broker
部署kafka實例的服務器節點 - topic
消息組織的單元,publish/subscribe的對象 - partition
每個topic由1個或者多個partition組成。分區在物理層面,不同分區對應着不同的數據文件。record按照順序追加寫到分區內。分區提高了kafka的可擴展性和併發吞吐性能。 - record
實際寫入到kafka中的消息記錄,每個record包含一個key、value和timesatmp - producer
生產者,向Kafka中發送record - consumer
消費者,從kafka中消費record - consumer group
消費組,一個消費可以訂閱多個topic,一個topic中的partition只能被一個消費組內的一個消費者消費,但是可以可以同時被不同的消費組消費
基本原理
Topics和Logs
一個topic是一個類別,是消息記錄發佈和訂閱的對象。
topic內部的消息記錄按照partition(分區)組織存儲,publish到該topic的消息記錄會均勻的寫入到各個partition,如下圖所示(官網複製)
partition內部,消息記錄以有序的、不可更改的次序追加寫方式進行組織,每個消息記錄被分配一個序列ID來唯一標示,該序列ID稱之爲offset。
用戶可以對topic內部的消息記錄設置過期時間,在有效期內,kakka集羣會持久化的存儲發佈到到該集羣的消息記錄,不管該消息記錄是否被消費過。過期的消息記錄會被kafaka刪除,以釋放空間。kafka的存儲方式決定了其性能不會隨着數據量的增加而下降,所以無需擔心存儲長時間的數據,我們要考慮的是kafka集羣的存儲空間是否充足。
對每個consumer,唯一需要維護的元數據是其消費的offset,該offset由consumer自己維護。通常情況下,在consumer消費消息記錄時,consumer會線性增加其offset;不過consumer也可以根據需求任意修改其offset。這些特性使得consumer的增加和刪除對集羣和其他consumer影響非常小。
對於topic內部partition的分區設計,其目的主要有兩個:線性擴展topic的存儲空間(不受限於單個server存儲的限制);提高併發,以提升性能。
Distribution
topic的partitions分佈在kafka集羣的servers上,每個server處理一個partition的數據和請求。每個partition可以配置副本數來冗災,每個partition會有一個server作爲leader角色,0個或者多個servers作爲followers。leader server處理該partiton的讀寫請求,followers被動的從leader server複製數據做備份。如果leader server掛掉,followers中的一個自動升級爲leader server。同時每個即要是一些partition的leader,又要是其他一些其他paritition的followers,以此來平衡集羣。
Producers
Producers發佈數據到它們選定的topic。producer負責消息記錄具體發佈到哪個partition,算法可以是簡單的round-robin來做負載均衡,也可以基於消息記錄中相關key來做路由。
Consumers
consumers用consumer group進行組織,kafka topic訂閱的對象是consumer group,topic中每條消息記錄會被傳遞到每個訂閱的consumer group中的一個consumer實例。
如果所有的consumer實例都屬於一個consumer group,那麼所有的消息記錄都會被均衡的傳遞給響應的consumer實例。
一個2個server的kafka集羣,包含4個parititons(P0-P3),有兩個消費組對其進行了訂閱。消費組A有2個consumer實例,消費組B有4個consumer實例。如下圖
實際的實現中,topic的每個parition會唯一被每個訂閱的消費組中的一個consumer實例消費,如果有新的consumer加入消費組,新加入的consumer實例會從該消費組的其他consumer實例接管一些partitions;如果一個consumer掛掉了,其消費的partitions會被剩餘的consumer實例獲取。
kafka只提供partition內部的保序,不同的partition之間並沒有順序可言。對大部分應用程序而言,partition內部的保序和按照key進行數據分區已經可以滿足其順序需求。如果需要全局保序,那麼一個topic只能包含一個partition,同時也意味這,一個消費組只能有一個consumer實例去消費topic數據。
Guarantees
kafka提供瞭如下保證:
- 被髮送到同一個partition的消息會按照其發送的順序進行追加寫入到parititon。即,如果M1和M2被同一個producer發送,M1先被髮送,那麼M1的offset將會比M2的小,且先被寫入。
- consumer實例看到的消息順序是消息存儲的順序
- N副本的topic,允許N-1臺server故障,而不丟失任何提交的日誌。