天天看點

吊打面試官系列:從架構開始闡述,Kafka為什麼這麼快?

一文帶你了解kafka為什麼那麼快?

1.首先來說一下我們為什麼要使用消息系統

在沒有使用消息系統之前,許多傳統的系統業務對于消息的處理一般會采用串行方式或者并行方法;

例如,你去網站注冊一個賬号,下面是串行跟并行的處理方式。

串行方式:

使用者注冊例子:使用者主責,将注冊資訊記錄到資料庫後,發送注冊消息郵件,再發送注冊短信驗證,每個過程小号50毫秒,一共就需要150毫秒

吊打面試官系列:從架構開始闡述,Kafka為什麼這麼快?
吊打面試官系列:從架構開始闡述,Kafka為什麼這麼快?

消息系統:

消息系統負責将資料從一個應用程式傳送到另一個應用程式,是以應用程式可以專注于資料,但是不必擔心 如何共享它。分布式消息系統基于可靠的消息隊列的概念。消息在用戶端應用程式和消息傳遞系統之間的異步排隊。

2.消息系統的分類:

點對點:

主要采用的隊列的方式進行消息傳遞,如A->B ,A生産B消費,當B消費的隊列中的資料,那麼隊列的資料就會被消費,也就是删除掉。

釋出-訂閱:

主要有三大元件:

主題:一個消息的分類,假如有一類的消息全部都是訂單,一類全部都是關于使用者的,一類全部都是關于訂單的。那麼就根據這些建立不同的主題存放不同的東西。

釋出者:将消息通過主動推送的方式推送給消息系統

訂閱者:可以采用拉,推的方式從消息系統中擷取資料

3.kafka的應用場景以及架構

apache kafka是一個分布式釋出-訂閱消息系統和一個強大的消息隊列,使用scala語言編寫是一個分布式,分區的,多副本的,多訂閱者的日志系統,可以用于搜尋日志,監控日志,通路日志等。

kafka架構圖:

吊打面試官系列:從架構開始闡述,Kafka為什麼這麼快?

Prodecers:生産者,主要用于生産資料。之後儲存到kafka叢集。

Consumers:叢集的消費者,從叢集中對生産者生産的資料進行消費。

Connectors:允許建構和運作可重用的生産者或者消費者,能夠把kafka主題連接配接到現有的應用程式或資料系統。例如:一個連 接到關系資料庫的連接配接器可能會擷取每個表的變化。

Stream processors:允許應用程式充當流處理器(stream processor),從一個或者多個主題擷取輸入流,并生産一個輸出流到一個或 者多個主題,能夠有效的變化輸入流為輸出流。

相關術語說明:

Broker:kafka叢集中包含一個或者多個服務執行個體,這種服務執行個體被稱為Broker

Topic:每條釋出到kafka叢集的消息都有一個類别,這個類别就叫做Topic

Partition:Partition是一個實體上的概念,每個Topic包含一個或者多個Partition (分區)

Producer:負責釋出消息到kafka的Broker中。

Consumer:消息消費者,向kafka的broker中讀取消息的用戶端

Consumer Group:每一個Consumer屬于一個特定的Consumer Group(可以為每個Consumer指定 groupName)

架構關系圖:

吊打面試官系列:從架構開始闡述,Kafka為什麼這麼快?

流程介紹:Zookeeper是一個分布式的,開放源碼的,使用者分布式的協調服務,生産者push資料到叢集,消費者通過pull進行拉取,但不管是生産者還是消費者的動作都需要zookeeper的管理。他的作用就是,生産者push資料到kafka叢集,就必須要找到kafka叢集的節點在哪裡,這些都是通過zookeeper去尋找的。消費者消費哪一條資料,也需要zookeeper的支援,從zookeeper獲得offset,offset記錄上一次消費的資料消費到哪裡,這樣就可以接着下一條資料進行消費。

kafka Partition offset

offset是一個long類型數字,它唯一辨別了一條消息,消費者通過(offset,partition,topic)跟蹤記錄。

任何釋出到此partition的消息都會被直接追加到log檔案的尾部,每條消息在檔案中的位置稱為offset(偏移量)。 記錄到上一次消費的位置,之後跟蹤到下一次接着上一次消費的位置進行繼續消費。保證了每次都從下一條開始消費,不會重複消費也不會丢失消費。

kafka為什麼那麼快主要從下面4個方面進行了解:

1.kafka的儲存設計方面

在Kafka檔案存儲中,同一個topic下有多個不同partition,每個partition為一個目錄,partiton命名規則為topic名稱+有序序号,第一個partiton序号從0開始,序号最大值為partitions數量減1。每個partition(目錄)被平均配置設定到多個大小相等segment(段)資料檔案中。但每個段segment file消息數量不一定相等,通過多個小檔案段,就容易定期清除或删除已經消費完檔案,減少磁盤占用。每一個sgement又包含了index檔案和log檔案,可以快速定位資料,通過index中繼資料全部映射到memory,可以避免segment file的IO磁盤操作。

2.利用Page cache+mmap

page cache用于緩存檔案的頁資料,頁是邏輯上的概念,是以page cache是與檔案系統同級的;他的作用就是加速資料的IO,寫資料的時候首先寫入緩存,将寫入的頁進行标記為dirty,之後向外部存儲flush;讀資料的時候就先讀取緩存,沒有讀取到再去外部存儲讀取。page cache中的每個檔案都是一棵基數樹,樹的每個節點都是一個頁。根據檔案内的偏移量就可以快速定位到所在的頁。

為什麼kafka要使用page cache 進行儲存管理

1.JVM中一切都是對象,資料的對象儲存會浪費空間

2.使用JVM管理,會降低吞吐量

3,如果系統程式崩潰管理的資料就會丢失,造成嚴重後果

mmap即是Memory Mapped Files 記憶體檔案映射,可以把實體上的磁盤檔案跟page cache進行映射,讓程序可以讀寫記憶體,有助于資料讀寫與磁盤的互動

3.kafka的批量壓縮設計

在大企業中,資料的流動時極快的,對于消息隊列很多的情況加,系統要面臨的問題就是不僅僅是磁盤的IO,更多的是網絡的IO。是以消息的壓縮對于kafka的性能來說就顯得尤其重要。

Kafka 中,壓縮可能發生在兩個地方:生産者端和 Broker 端,kafka采用批量壓縮的方式,而不是采用單個消息隊列壓縮。 如果對每一個消息都進行壓縮,壓縮的效率就會大大降低。kafka支援很多種壓縮方式,允許使用遞歸的消息集合。

4.kafka的消息讀寫過程

1.Producer根據zookeeper連接配接到或者的broker,從zookeeper節點找到該partition的leader

2.producer把需要發送的消息發給該leader,leader把消息寫入到log,follows從leader拉取消息,寫入到本地的log之後向leader發送ACK,leader收到後向producer發送ACK

生産者把經過批量壓縮的資料發送給broker之後,beocker就通過函數映射壓縮檔案的位址到記憶體,之後就可以根據這個函數進行寫入的操作,寫入的時候會直接進入到PageCache,之火由os的線程異步重新整理到磁盤,達到一次性能優化。

kafka在讀取資料的時候,會判斷資料是否存在于page cache,如果存在的話就會直接從page cache中消費,是以消費實時資料的速度就會快很多。

5.ZeroCopy

在linux中有兩個上下文,分别是核心态跟使用者态,我們将一個File讀取并發送出去需要經曆4次Copy:

1.調用read,将檔案拷貝到了kernel核心态

2.CPU控制 kernel态的資料copy到使用者态

3.調用write時,user态下的内容會copy到核心态的socket的buffer中

4.最後将核心态socket buffer的資料copy到網卡裝置中傳送

缺點就是增加了上下文切換、浪費了2次無效拷貝

ZeroCopy技術:

請求kernel直接把disk的data傳輸給socket,而不是通過應用程式傳輸。Zero copy大大提高了應用程式的性能,減少不必要的核心緩沖區跟使用者緩沖區間的拷貝,進而減少CPU的開銷和減少了kernel和user模式的上下文切換,達到性能的提升

對應零貝技術有mmap及sendfile:

1.mmap:小檔案傳輸快

2.sendfile:大檔案傳輸比mmap快

應用:Kafka、Netty、RocketMQ等消息隊列都采用了零拷貝技術

到這裡kafka為什麼這麼快這個問題,相信你就可以跟面試官對答如流了!