1.關於kafka
Kafka是由Apache軟件基金會開發的一個開源消息隊列,由Scala和Java編寫。
相關文章參考:
- MQ: 消息隊列常見應用場景及主流消息隊列ActiveMQ、RabbitMQ、RocketMQ和Kafka的簡單對比
- MQ: kafka的Java接入與入門示例(topic增刪改查,Producer多參發送,Consumer多分區接受)
2.工作原理
首先,我們來kafka的整體數據流架構圖:
2.1.相關術語
上圖中,涉及以下術語:
- Producer:消息生產者,生產消息,然後
push
到消息隊列。 - Broker:消息中間人,消息的存儲容器。
- Consumer:消息消費者,從消息隊列中
pull
數據,進行消費。 - Topic:消息話題,消息在業務角度的劃分,用於區分不同種類的消息。
- Partition:消息分區,消息在存儲上的邏輯劃分(10條消息,5條存於分區1,5條存於分區2),用於加快消息消費速度,提示消息消費吞吐量。
- Consumer Group:消息消費者組,可以區分不同種類的消費者,用於實現點對點模式和發佈訂閱模式。
其他術語Key、Leader、Replicas、ISR在後續章節中逐步介紹。
2.2.消息存儲相關
想要弄清楚kafka的工作原理,首先應該對消息的存儲結構進行掌握。
區分消息的邏輯概念是話題Topic,Topic存儲於Broker之中,如下圖所示:
爲了便於理解,我們直接看圖說話
:
Broker與Topic
- 圖中的Broker集羣實際是由3個Broker構成的,其實每個Broker就是一個Kafka服務節點。
- 圖中共有3個Topic:橙色爲
Topic-0
,提夫尼藍爲Topic-2
,深藍色爲Topic-1
。
Topic與Partition
- 單看
Topic-0-Partition-0
:Broker中消息容器的最小單元爲Partition,Partition存儲了一條條的消息。 - 單看Broker-1:
- Topic可有多個Partition,如
Topic-1
有2個分區;若共計9條消息,則可能2個分區分別存儲了4、5條消息。 - Topic可只有1個Partition,如
Topic-2
;若共計9條消息,則這個單獨的分區存儲了9條消息。 - 分區存儲哪條消息取決於Producer發送消息時的選擇,相關內容後續章節介紹。
- Topic可有多個Partition,如
多副本冗餘機制
- 單看Topic-2:
- 粗框Partition表示Leader(主)分區,負責讀寫消息;
- 細框Partition表示Replicas(從)分區,被動複製Leader,複製冗餘容災。
- 如果Broker-1掛掉,則
Topic-2-Partition-0
的Leader掛掉,從其餘兩個Replicas中選舉出新的Leader繼續提供服務。 - Replicas的數量不能超過Broker的數量,因爲一個Broker上存在多個Replicas與存在一個Replicas的效果是一樣的。
- Replicas的數量可以小於Broker的數量。
- 再看Topic-0:
- 每個Partition都會有Leader和Replicas。
- kafka會
儘量打散
同一Topic的分區Leader,如圖,3個Leader分佈於3個Broker中。 - 分區Leader的分散分佈不是絕對的,比方說此時只有一個Broker,則3個分區都是Leader,都分佈在同一個Broker上。
- 分區的數量可以大於Broker的數量,因爲分區存在的目的是加快消息消費速度,與冗餘容災無關。
相對有序性
- Topic-0的3個分區的消息分別是:
1、2、3
,4、5、6
,7、8、9
。 - Topic-1的2個分區的消息分別是:
1、2、8、9
,4、5、6、7
。 - Topic-2的1個分區的消息是:
1、2、3、4、5、6、7、8、9
。 - 相對有序性:單個partition內消息有序,多個partition間消息無序。
- kafka通過在Partition中標記offset,來記錄消息的順序。
- 如果業務場景追求全局有序性,則每個Topic只配置一個Partition即可。
Producer消息生產語義
- 消息最多發送一次:第一種方式:異步發送消息。第二種方式:同步發送消息並且重試次數爲0。
- 消息最少發送一次:同步發送消息,失敗與超時重試,知道消息發送成功。
2.3.消息生產相關
搞清楚消息的存儲之後,我們再來看消息的生產:
爲了便於理解,我們直接看圖說話
:
- ①:一個Producer可以向多個Topic、多個Partition發送消息。
- ②:多個Producer可以向同一個Topic、同一個Partition發送消息。
- ③:消息發送參數:
( topic, [partition], [key], message )
- topic必填;message即消息本身,必填。
- partition選填。如未填,則判斷key是否存在,若key不存在,則隨機選分區。
- key選填。如填寫,則根據key哈希之後取模分區數量的結果,選擇分區;如未填,則隨機選分區。
- 隨機選分區:優先使用緩存的隨機分區;若緩存爲空,則隨機選分區,然後將隨機分區存入緩存,供下次使用。
2.4.消息消費相關
我們繼續學習消息的消費:
爲了便於理解,我們直接看圖說話
:
消息消費方式
- 消息消費的箭頭方向:kafka消費消息的方式只有pull,沒有push。
- push的優勢在於實時性高,但是容易因Producer生產消息過快壓垮Consumer。
- pull的優勢在於可以控制消費速度,但是容易出現空輪訓。
- kafka對pull的優化:通過配置使得只有當數據存在且到達一定量級,才進行pull。
Consumer Group與Consumer
- ⑥⑦:一個Consumer-Group可以有多個Consumer,也可以只有1個Consumer。
- ⑤:一個Topic-Partition的消息可以被多個Consumer-Group消費,注意:是Consumer-Group,而不是Consumer。
- ⑦:若Consumer-Group只有1個Consumer,則這個Partition中的所有消息都被這個Consumer消費。
- ⑥:若Consumer-Group有多個Consumer,且在正常連接期間:
- 單個Partition的消息只能被其中一個Consumer消費,不能被Consumer-Group內的多個Consumer消費。
- 多個Partition的消息可以被一個Consumer消費。
- 若單個Topic的分區數量小於Consumer-Group內的Consumer個數,則會存在Consumer接受不到這個Topic的消息。
Consumer消息消費語義
- 消息最多消費一次:1.讀取消息,2,確認offset,3.處理消息。
- 消息最少消費一次:1.讀取消息,2.處理消息,3.確認offset。