天天看點

Kafka之工作流程分析

Kafka之工作流程分析

kafka核心組成

  producer采用推(push)模式将消息釋出到broker,每條消息都被追加(append)到分區(patition)中,屬于順序寫磁盤(順序寫磁盤效率比随機寫記憶體要高,保障kafka吞吐率)。

  消息發送時都被發送到一個topic,其本質就是一個目錄,而topic是由一些Partition Logs(分區日志)組成,其組織結構如下圖所示:  

Kafka之工作流程分析
Kafka之工作流程分析

  我們可以看到,每個Partition中的消息都是有序的,生産的消息被不斷追加到Partition log上,其中的每一個消息都被賦予了一個唯一的offset值。

(1)分區的原因

  1)友善在叢集中擴充,每個Partition可以通過調整以适應它所在的機器,而一個topic又可以有多個Partition組成,是以整個叢集就可以适應任意大小的資料了;

  2)可以提高并發,因為可以以Partition為機關讀寫了。

(2)分區的原則

  1)指定了patition,則直接使用;

  2)未指定patition但指定key,通過對key的value進行hash出一個patition;

  3)patition和key都未指定,使用輪詢選出一個patition。

  同一個partition可能會有多個replication(對應 server.properties 配置中的 default.replication.factor=N)。沒有replication的情況下,一旦broker 當機,其上所有 patition 的資料都不可被消費,同時producer也不能再将資料存于其上的patition。引入replication之後,同一個partition可能會有多個replication,而這時需要在這些replication之間選出一個leader,producer和consumer隻與這個leader互動,其它replication作為follower從leader 中複制資料。

producer寫入消息流程如下:

1、Broker:安裝Kafka服務的那台叢集就是一個broker(broker的id要全局唯一)

2、Producer:消息的生産者,負責将資料寫入到broker中(push)

3、Consumer:消息的消費者,負責從kafka中讀取資料(pull),老版本的消費者需要依賴zk,新版本的不需要

4、Topic:主題,相當于是資料的一個分類,不同topic存放不同的資料

5、replication:副本,資料儲存多少份(保證資料不丢)

6、partition:分區,是一個實體分區,一個分區就是一個檔案,一個topic可以有一到多個分區,每一個分區都有自己的副本。

7、Consumer Group:消費者組,一個topic可以有多個消費者同時消費,多個消費者如果在一個消費者組中,那麼他們不能重複消費資料

  實體上把topic分成一個或多個patition(對應server.properties 中的num.partitions=3配置),每個patition實體上對應一個檔案夾(該檔案夾存儲該patition的所有消息和索引檔案),如下:

無論消息是否被消費,kafka都會保留所有消息。有兩種政策可以删除舊資料:

  1)基于時間:log.retention.hours=168

  2)基于大小:log.retention.bytes=1073741824

需要注意的是,因為Kafka讀取特定消息的時間複雜度為O(1),即與檔案大小無關,是以這裡删除過期檔案與提高 Kafka 性能無關。

Kafka之工作流程分析

注意:producer不在zk中注冊,消費者在zk中注冊。

  kafka提供了兩套consumer API:進階Consumer API和低級Consumer API。

1)進階API優點

  進階API 寫起來簡單

    不需要自行去管理offset,系統通過zookeeper自行管理。

    不需要管理分區,副本等情況,系統自動管理。

  消費者斷線會自動根據上一次記錄在zookeeper中的offset去接着擷取資料(預設設定1分鐘更新一下zookeeper中存的offset)

  可以使用group來區分對同一個topic 的不同程式通路分離開來(不同的group記錄不同的offset,這樣不同程式讀取同一個topic才不會因為offset互相影響)

2)進階API缺點

  不能自行控制offset(對于某些特殊需求來說)

  不能細化控制如分區、副本、zk等

1)低級 API 優點

  能夠讓開發者自己控制offset,想從哪裡讀取就從哪裡讀取。

  自行控制連接配接分區,對分區自定義進行負載均衡

  對zookeeper的依賴性降低(如:offset不一定非要靠zk存儲,自行存儲offset即可,比如存在檔案或者記憶體中)

2)低級API缺點

  太過複雜,需要自行控制offset,連接配接哪個分區,找到分區leader 等。

Kafka之工作流程分析

  消費者是以consumer group消費者組的方式工作,由一個或者多個消費者組成一個組,共同消費一個topic。每個分區在同一時間隻能由group中的一個消費者讀取,但是多個group可以同時消費這個partition。在圖中,有一個由三個消費者組成的group,有一個消費者讀取主題中的兩個分區,另外兩個分别讀取一個分區。某個消費者讀取某個分區,也可以叫做某個消費者是某個分區的擁有者。

  在這種情況下,消費者可以通過水準擴充的方式同時讀取大量的消息。另外,如果一個消費者失敗了,那麼其他的group成員會自動負載均衡讀取之前失敗的消費者讀取的分區。

   consumer采用pull(拉)模式從broker中讀取資料。

  push(推)模式很難适應消費速率不同的消費者,因為消息發送速率是由broker決定的。它的目标是盡可能以最快速度傳遞消息,但是這樣很容易造成consumer來不及處理消息,典型的表現就是拒絕服務以及網絡擁塞。而pull模式則可以根據consumer的消費能力以适當的速率消費消息。

  對于Kafka而言,pull模式更合适,它可簡化broker的設計,consumer可自主要制消費消息的速率,同時consumer可以自己控制消費方式——即可批量消費也可逐條消費,同時還能選擇不同的送出方式進而實作不同的傳輸語義。

pull模式不足之處是,如果kafka沒有資料,消費者可能會陷入循環中,一直等待資料到達。為了避免這種情況,我們在我們的拉請求中有參數,允許消費者請求在等待資料到達的“長輪詢”中進行阻塞(并且可選地等待到給定的位元組數,以確定大的傳輸大小)。

  1)需求:測試同一個消費者組中的消費者,同一時刻隻能有一個消費者消費。

  2)案例實操

  (1)在hadoop1、hadoop2上修改/home/bigdata/kafka/config/consumer.properties配置檔案中的group.id屬性為任意組名。

  (2)在hadoop1、hadoop2上分别啟動消費者

  (3)在hadoop104上啟動生産者

  (4)檢視hadoop1和hadoop2的接收者

    同一時刻隻有一個消費者接收到消息。

做自己的太陽,成為别人的光!

繼續閱讀