《Kafka筆記》1、Kafka初識

一、初識Kafka

1 apache kafka簡介

Kafka是由Apache軟件基金會開發的一個開源流處理平台,由Scala和Java編寫。Kafka是一種高吞吐量的分佈式發佈訂閱消息系統,它可以收集並處理用戶在網站中的所有動作流數據以及物聯網設備的採樣信息。

Apache Kafka是Apache軟件基金會的開源的流處理平台,該平台提供了消息的訂閱與發佈的消息隊列,一般用作系統間解耦異步通信削峰填谷等作用。同時Kafka又提供了Kafka streaming插件包實現了實時在線流處理。相比較一些專業的流處理框架不同,Kafka-Streaming計算是運行在應用端,具有簡單、入門要求低、部署方便等優點。

  • 消息隊列Message Queue
  • Kafka Streaming 流處理

2 消息中間件kafka的使用場景

2.1 訂閱與發佈隊列

1、系統間解耦
2、異步通信
3、削峰填谷

消息中間件kafka的作用

2.2 流處理

1、Kafka streaming相比較於其他流處理框架,例如stom和spark,flink,kafka是應用在應用端的流處理。而stom,spark和flink都是運行在服務端的流處理框架。

2、所以kafak流,比stom,spark,flink的部署方便,運行的環境要求的比較低,同時無需開闢新的的服務器用來做流計算

3、所以kafka的流,被廣泛應用在分佈式,微服務領域

3 kafka對數據的管理形式

Message Queue : 消息隊列

消息隊列是一種在分佈式和大數據開發中不可或缺的中間件。在分佈式開發或者大數據開發中通常使用消息隊列進行緩衝、系統間解耦和削峰填谷等業務場景,常見的消息隊列工作模式大致會分為兩大類:

  • 至多一次:消息生產者將數據寫入消息系統,然後由消費者負責去拉去消息服務器中的消息,一旦消息被確認消費之後 ,由消息服務器主動刪除隊列中的數據,這種消費方式一般只允許被一個消費者消費,並且消息隊列中的數據不允許被重複消費,例如activeMQ。

  • 沒有限制:同上訴消費形式不同,生產者發佈完數據以後,該消息可以被多個消費者同時消費,並且同一個消費者可以多次消費消息服務器中的同一個記錄。主要是因為消息服務器一般可以長時間存儲海量消息。每個消費者都有自己的偏移量。例如Kafka

至多一次和重複消費對比

4 kafka基礎架構

1、Kafka集群(kafka往往通過多節點構成)以Topic形式負責分類集群中的Record(消息)每一個Record屬於一個Topic。每個Topic底層都會對應一組分區的日誌用於持久化Topic中的Record。

2、同時在Kafka集群中,Topic的每一個日誌的分區都一定會有1個Borker(機器節點)擔當該分區的Leader,其他的Broker擔當該分區的follower,Leader負責分區數據的讀寫操作,follower負責同步改分區的數據。

3、這樣如果分區的Leader宕機,該分區的其他follower會選取出新的leader繼續負責該分區數據的讀寫。

4、每個分區也都有自己的副本(分區冗餘相互備份)。

5、其中集群的中Leader的監控和Topic的部分元數據是存儲在Zookeeper中.

6、生產者發送的消息,只屬於一個topic。消費者可以訂閱多個topic。一旦訂閱者訂閱的topic有數據產生,便可以fetch它

Kafka架構

7、hash(key)%分區數:不僅能夠使消息均勻的落入我們的分區中,而且還可以是相同的key落入到相同的分區

8、分區因子:表示我們的每個分區要在集群中存多少份

9、kafka中,所有的broker節點,既是某個分區的leader也可能是另外分區的follower。

Kafka架構詳解

10、如上圖,如果broker-0宕機,zookeeper會檢測到我們Topic01的partion0的leader宕機。會協調重新在broker-1和broker-2選擇partion0的leader。節點broker-0恢復服務後,我們zk集群會重新協調分配

Kafka集群節點宕機

5 Kafka的主題(topics)和日誌(logs)

5.1 消息發佈端

1、Kafka中所有消息(record)是通過Topic為單位進行管理,每個Kafka中的Topic通常會有多個訂閱者(也叫消費者),負責訂閱發送到改Topic中的數據。Kafka負責管理集群中每個Topic的一組日誌分區數據。

2、生產者將數據發佈到相應的Topic。負責選擇將哪個記錄(消息)分發送到Topic中的哪個Partition。例如可以round-robin(輪詢)方式完成此操作,然而這種僅是為了平衡負載。也可以根據某些語義分區功能(例如基於記錄中的Key)進行此操作。

3、每組日誌分區是一個有序的不可變的的日誌序列(先進先出fifo),分區中的每一個Record都被分配了唯一的序列編號稱為是offset(當前消息在序列中的位置),Kafka 集群會持久化所有發佈到Topic中的Record信息,該Record的持久化的時間是通過配置文件指定,默認是168小時(7天)。log.retention.hours=168

5、Kafka底層會定期的檢查日誌文件,然後將過期的數據從log中移除,由於Kafka底層使用硬盤存儲日誌文件,因此使用Kafka長時間緩存一些日誌文件是不存在問題的。

6、由於遵循分區策略,每個partion的數據並不是相同的,也並非全局有序的,既並非保證topic全局先進先出。每個分區內部是有序的,總體構成的我們生產者生產在這個topic的全集的數據。如果一定要保證在一個topic中全局有序,我們可以指定topic中的分區數為1個即可

kafka分區消息寫入

7、每個分區,都有集群節點一個節點擔任leader。那麼如果要保證寫入速度快,我們只需要增加topic中的分區數目即可。既增加分區可以提升kafka的寫入性能

5.2 消息消費端

1、在消費者消費Topic中數據的時候,每個消費者會維護本次消費對應分區的偏移量,消費者會在消費完一個批次的數據之後,會將本次消費的偏移量提交給Kafka集群,因此對於每個消費者而言可以隨意的控制改消費者的偏移量。因此在Kafka中,消費者可以從一個topic分區中的任意位置讀取隊列數據,由於每個消費者控制了自己的消費的偏移量,因此多個消費者之間彼此相互獨立。消費者每次提交給kafka集群的偏移量,是該消費者下次需要讀取的起始位置

kafka消費數據

2、Kafka中對Topic實現日誌分區的有以下目的:

  • 首先,它們允許日誌擴展到超出單個服務器所能容納的大小。每個單獨的分區都必須適合託管它的服務器,但是一個Topic可能有很多分區,因此它可以處理任意數量的數據。

  • 其次每個服務器充當其某些分區的Leader,也可能充當其他分區的Follwer,因此群集中的負載得到了很好的平衡。

6 生產者&消費者&消費者組

1、消費者使用Consumer Group名稱標記自己,並且發佈到Topic的每條記錄都會傳遞到每個訂閱Consumer Group中的一個消費者實例。如果所有Consumer實例都具有相同的Consumer Group,那麼Topic中的記錄會在該ConsumerGroup中的Consumer實例進行均分消費;如果所有Consumer實例具有不同的ConsumerGroup,則每條記錄將廣播到所有Consumer Group進程

解釋:對於kafka而言,只保證發送到topic中的每條消息,一定會發送到ConsumerGroup,但是到底發送給了ConsumerGroup的哪個Consumer消費者實例,取決於消費者實例的一些配置

2、更常見的是,我們發現Topic具有少量的Consumer Group,每個Consumer Group可以理解為一個「邏輯的訂閱者」。每個Consumer Group均由許多Consumer實例組成,以實現可伸縮性和容錯能力。這無非就是發佈-訂閱模型,其中訂閱者是消費者的集群(消費者組)而不是單個進程。這種消費方式Kafka會將Topic按照分區的方式均分給一個Consumer Group下的實例,如果ConsumerGroup下有新的成員介入,則新介入的Consumer實例會去接管ConsumerGroup內其他消費者負責的某些分區,同樣如果一下ConsumerGroup下的有其他Consumer實例宕機,則由改ConsumerGroup其他實例接管

解釋:同一個消費者組,只能均分分區消費,不能重複消費某一個分區,不管該組有多少個消費者。不同消費者組,互不影響。見下圖

3、由於Kafka的Topic的分區策略,因此Kafka僅提供分區中記錄的有序性,也就意味着相同Topic的不同分區記錄之間無順序。因為針對於絕大多數的大數據應用和使用場景, 使用分區內部有序或者使用key進行分區策略已經足夠滿足絕大多數應用場景。但是,如果您需要記錄全局有序,則可以通過只有一個分區Topic來實現,儘管這將意味着每個ConsumerGroup只有一個Consumer進程,意味着我們會損傷kafka的高吞吐量

消費者組消費

解釋:一般消費者組裏面消費者的數目,不會大於分區數目。如果大於,那麼會存在某個消費者不消費,浪費了資源。例如上圖在消費者組B增加一個消費者c5,那麼由於c1,c2,c3,c4已經安排好了,c5隻能處於空閑狀態。但是如果c1,c2,c3,c4的某台宕機,會有c5來接管

消費者組冗餘情況

原則意義上講,topic中的分區越多,我們定義消費者組中的消費者只需要保持一致,並行消費能力增強,就可以加快消費。本質還是加大topic中的分區數目。

所以增加kafka的topic中的分區數目,不僅僅可以增加我們的存儲,寫入能力。也可以間接增加我們並行消費topic的速度和能力

7 順序寫入和Zero-copy(高性能之道)

7.1 寫入性能提升之道(順序寫和mmap)

1、Kafka的特性之一就是高吞吐率,但是Kafka的消息是保存或緩存在磁盤上的,一般認為在磁盤上讀寫數據是會降低性能的,但是Kafka即使是普通的服務器,Kafka也可以輕鬆支持每秒百萬級的寫入請求,超過了大部分的消息中間件,這種特性也使得Kafka在日誌處理等海量數據場景廣泛應用。Kafka會把收到的消息都寫入到硬盤中,防止丟失數據。為了優化寫入速度Kafka採用了兩個技術順序寫入MMFile(內存映射文件)

2、因為硬盤是機械結構,每次讀寫都會尋址->寫入,其中尋址是一個「機械動作」,它是最耗時的(移動磁頭)。所以硬盤最討厭隨機I/O,最喜歡順序I/O。為了提高讀寫硬盤的速度,Kafka就是使用順序I/O。這樣省去了大量的內存開銷以及節省了IO尋址的時間。但是單純的使用順序寫入,Kafka的寫入性能也不可能和內存進行對比,因此Kafka的數據並不是實時的寫入硬盤中

3、Kafka充分利用了現代操作系統分頁存儲(page catch)來利用內存提高I/O效率。Memory Mapped Files(後面簡稱mmap)也稱為內存映射文件,在64位操作系統中一般可以表示20G的數據文件,它的工作原理是直接利用操作系統的Page實現文件到物理內存的直接映射。完成MMP映射後,用戶對內存的所有操作會被操作系統自動的刷新到磁盤上,極大地降低了IO使用率

註:kafka直接把數據寫入到內核級別的內存中,算是寫入成功了,kafka不會主動刷新內核級別的內存上的數據到磁盤上。而是由操作系統來刷新,極大降低io的使用率。對於用戶而言,我們感知的kafak的寫入效率,直接逼近與內存寫入

Kafka順序寫和mmap

7.2 消費性能提升之道(zero-copy)

1、Kafka服務器在響應客戶端讀取的時候,底層使用ZeroCopy技術,直接將磁盤無需拷貝到用戶空間,而是直接將數據通過內核空間傳遞輸出,數據並沒有抵達用戶空間

2、傳統IO操作

  • 1、用戶進程調用read等系統調用向操作系統發出IO請求,請求讀取數據到自己的內存緩衝區中。自己進入阻塞狀態。
  • 2、操作系統收到請求後,進一步將IO請求發送磁盤。
  • 3、磁盤驅動器收到內核的IO請求,把數據從磁盤讀取到驅動器的緩衝中。此時不佔用CPU。當驅動器的緩衝區被讀滿後,向內核發起中斷信號告知自己緩衝區已滿。
  • 4、內核收到中斷,使用CPU時間將磁盤驅動器的緩存中的數據拷貝到內核緩衝區中。
  • 5、如果內核緩衝區的數據少於用戶申請的讀的數據,重複步驟3跟步驟4,直到內核緩衝區的數據足夠多為止。
  • 6、將數據從內核緩衝區拷貝到用戶緩衝區,同時從系統調用中返回。完成任務

3、DMA讀取

  • 1、用戶進程調用read等系統調用向操作系統發出IO請求,請求讀取數據到自己的內存緩衝區中。自己進入阻塞狀態。
  • 2、操作系統收到請求後,進一步將IO請求發送DMA。然後讓CPU干別的活去。
  • 3、DMA進一步將IO請求發送給磁盤。
  • 4.磁盤驅動器收到DMA的IO請求,把數據從磁盤讀取到驅動器的緩衝中。當驅動器的緩衝區被讀滿後,向DMA發起中斷信號告知自己緩衝區已滿。
  • 4、DMA收到磁盤驅動器的信號,將磁盤驅動器的緩存中的數據拷貝到內核緩衝區中。此時不佔用CPU。這個時候只要內核緩衝區的數據少於用戶申請的讀的數據,內核就會一直重複步驟3跟步驟4,直到內核緩衝區的數據足夠多為止。
  • 5、當DMA讀取了足夠多的數據,就會發送中斷信號給CPU。
  • 6、CPU收到DMA的信號,知道數據已經準備好,於是將數據從內核拷貝到用戶空間,系統調用返回。

註:跟IO中斷模式相比,DMA模式下,DMA就是CPU的一個代理,它負責了一部分的拷貝工作,從而減輕了CPU的負擔。DMA的優點就是:中斷少,CPU負擔低。

4、網絡IO

  • 一般方案:

1、文件在磁盤中數據被copy到內核緩衝區

2、從內核緩衝區copy到用戶緩衝區

3、用戶緩衝區copy到內核與socket相關的緩衝區。

4、數據從socket緩衝區copy到相關協議引擎發送出去

  • Zero拷貝

1、文件在磁盤中數據被copy到內核緩衝區

2、從內核緩衝區copy到內核與socket相關的緩衝區。

3、數據從socket緩衝區copy到相關協議引擎發送出去

常規io

zeroCopy

本章小結

1.隊列的使用場景

  • 解耦、異步通信、削峰填谷

2.Kafka架構和基本概念

  • topic、分區/分區副本因子、offset、順序寫、zeroCopy
  • 生產者、消費者|消費者組
Tags: