初探消息隊列kafka

基本概念

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,如下圖所示(官網複製)
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-5AgIAD9X-1584366722393)(http://km.oa.com/files/photos/pictures//20191223//1577106923_37.png)]
partition內部,消息記錄以有序的、不可更改的次序追加寫方式進行組織,每個消息記錄被分配一個序列ID來唯一標示,該序列ID稱之爲offset。
用戶可以對topic內部的消息記錄設置過期時間,在有效期內,kakka集羣會持久化的存儲發佈到到該集羣的消息記錄,不管該消息記錄是否被消費過。過期的消息記錄會被kafaka刪除,以釋放空間。kafka的存儲方式決定了其性能不會隨着數據量的增加而下降,所以無需擔心存儲長時間的數據,我們要考慮的是kafka集羣的存儲空間是否充足。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-eI8Je2xC-1584366722394)(http://km.oa.com/files/photos/pictures//20191223//1577106941_73.png)]
對每個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實例。如下圖
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-0I4uKSGC-1584366722395)(http://km.oa.com/files/photos/pictures//20191223//1577106962_88.png)]
實際的實現中,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故障,而不丟失任何提交的日誌。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章