天天看點

MQ: 一張圖讀懂kafka工作原理

1.關于kafka

Kafka是由Apache軟體基金會開發的一個開源消息隊列,由Scala和Java編寫。

相關文章參考:

  • MQ: 消息隊列常見應用場景及主流消息隊列ActiveMQ、RabbitMQ、RocketMQ和Kafka的簡單對比
  • MQ: kafka的Java接入與入門示例(topic增删改查,Producer多參發送,Consumer多分區接受)

2.工作原理

首先,我們來kafka的整體資料流架構圖:

MQ: 一張圖讀懂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之中,如下圖所示:

MQ: 一張圖讀懂kafka工作原理

為了便于了解,我們直接

看圖說話

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-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。
  • 消息最少發送一次:同步發送消息,失敗與逾時重試,直到消息發送成功。

Partition、Replicas和Broker的計算方式

  • 假定Broker數量為n。
  • 将第i個Partition配置設定至第

    i % n

    個Broker上。
  • 将第i個Partition的第j個Replica分片值第

    (i + j) % n

    個Broker上。

2.3.消息生産相關

搞清楚消息的存儲之後,我們再來看消息的生産:

MQ: 一張圖讀懂kafka工作原理

為了便于了解,我們直接

看圖說話

  • ①:一個Producer可以向多個Topic、多個Partition發送消息。
  • ②:多個Producer可以向同一個Topic、同一個Partition發送消息。
  • ③:消息發送參數:

    ( topic, [partition], [key], message )

    • topic必填;message即消息本身,必填。
    • partition選填。如未填,則判斷key是否存在,若key不存在,則随機選分區。
    • key選填。如填寫,則根據key哈希之後取模分區數量的結果,選擇分區;如未填,則随機選分區。
    • 随機選分區:優先使用緩存的随機分區;若緩存為空,則随機選分區,然後将随機分區存入緩存,供下次使用。

2.4.消息消費相關

我們繼續學習消息的消費:

MQ: 一張圖讀懂kafka工作原理

為了便于了解,我們直接

看圖說話

消息消費方式

  • 消息消費的箭頭方向: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。

3.參考文獻

  • https://blog.csdn.net/lavorange/article/details/78970977
  • https://blog.csdn.net/qq_29186199/article/details/80827085
  • https://www.jianshu.com/p/d3e963ff8b70
  • Kafka源碼解讀—-key為nulll時Kafka如何選擇分區(Partition)
  • https://blog.csdn.net/caijiapeng0102/article/details/80765923