面試官問:kafka為什麼如此之快?

java旭陽 發佈 2023-06-02T11:28:31.867841+00:00

前言天下武功,唯快不破。同樣的,kafka在消息隊列領域,也是非常快的,這裡的塊指的是kafka在單位時間搬運的數據量大小,也就是吞吐量,下圖是搬運網上的一個性能測試結果,在同步發送場景下,單機Kafka的吞吐量高達17.3w/s,不愧是高吞吐量消息中間件的行業老大。

前言

天下武功,唯快不破。同樣的,kafka在消息隊列領域,也是非常快的,這裡的塊指的是kafka在單位時間搬運的數據量大小,也就是吞吐量,下圖是搬運網上的一個性能測試結果,在同步發送場景下,單機Kafka的吞吐量高達17.3w/s,不愧是高吞吐量消息中間件的行業老大。

那究竟是什麼原因讓kafka如此之快呢?這也是面試官非常喜歡問的問題。

四個原因

原因一:磁碟順序讀寫

生產者發送數據到kafka集群中,最終會寫入到磁碟中,會採用順序寫入的方式。消費者從kafka集群中獲取數據時,也是採用順序讀的方式。

無論是機械磁碟還是固態硬碟SSD,順序讀寫的速度都是遠大於隨機讀寫的。因為對於機械磁碟順序讀寫省去了磁頭頻繁尋址和旋轉碟片的開銷。而固態硬碟就更加複雜,這裡不展開闡述。

下圖是網上關於讀寫方式的性能比較。

  • 機械磁碟順序讀寫 53M/s,隨讀寫 316k/s
  • 固態硬碟順序讀寫 42M/s, 隨機讀寫 1000k/s

因而,由於kafka一般使用機械磁碟存儲消息,因為機械磁碟的價格遠小於固態硬碟SSD。

原因二:PageCache頁緩存技術

前面提到了kafka採用順序讀寫寫入到磁碟中,難道是直接kafka到磁碟嗎,實際上不是的,中間多了一道作業系統的PageCache頁緩存,可以理解為內存。

  • 當kafka有寫操作時,先將數據寫入PageCache中,然後在定時方式順序寫入到磁碟中。
  • 當讀操作發生時,先從PageCache中查找,如果找不到,再去磁碟中讀取。

通過頁緩存技術,更近一步的提高了讀寫的性能。

原因三:零拷貝技術

kafka之所以快的另外一個原因是採用了零拷貝技術。

首先我們來看下從磁碟讀取數據到網卡場景下,傳統IO的整個過程,如下圖所示:

傳統IO模型下,從磁碟讀取數據,寫到網卡設備中,經歷了4次用戶態和內核態之間的切換,以及4次數據的拷貝,包括CPU拷貝和DMA拷貝。這些操作都是十分損耗性能。

DMA, Direct Memory Access, 直接內存訪問是一些計算機總線架構提供的功能,它能使數據從附加設備(如磁碟驅動器)直接發送到計算機主板的內存上。

那能否減少這樣的切換和拷貝呢?答案是肯定的,不知道大家發下沒有,kafka的消息在應用層做任何轉換,怎麼存就怎麼取,你看連序列化、反序列化都是在生產者和消費者做的。所以kafka採用了sendfile的零拷貝技術

sendfile零拷貝技術在內核態將數據從PageCache拷貝到了Socket緩衝區,這樣就大大減少了不同形態的切換以及拷貝。

所謂的零拷貝技術不是指不發生拷貝,而是在用戶態沒有進行拷貝。

原因四:kafka分區架構和批量操作

一方面kafka的集群架構採用了多分區技術,並行度高。另外一方面,kafka採用了批量操作。生產者發送的消息先發送到一個隊列,然後有sender線程批量發送給kafka集群。

如何提高生產者的吞吐量?

kafka生產者提供的一些配置參數可以有助於提高生產者的吞吐量。

參數名稱

描述

buffer.memory

RecordAccumulator 緩衝區總大小,默認 32m。適當增加該值,可以提高吞吐量。

batch.size

緩衝區一批數據最大值,默認 16k。適當增加該值,可以提高吞吐量,但是如果該值設置太大,會導致數據傳輸延遲增加。

linger.ms

如果數據遲遲未達到 batch.size,sender線程等待 linger.time之後就會發送數據。單位 ms,默認值是 0ms,表示沒有延遲。生產環境建議該值大小為 5-100ms 之間。

compression.type

指定消息的壓縮方式,默認值為「none ",即默認情況下,消息不會被壓縮。該參數還可以配置為 "gzip","snappy" 和 "lz4"。對消息進行壓縮可以極大地減少網絡傳輸、降低網絡 I/O,從而提高整體的性能 。

如何提高消費者的吞吐量?

  1. 如果是Kafka消費能力不足,則可以考慮增加Topic的分區數,並且同時提升消費組的消費者數量,消費者數 = 分區數,並發度最高
  2. 如果是下游的數據處理不及時:提高每批次拉取的數量。批次拉取數據過少,使處理的數據小於生產的數據,也會造成數據積壓。
  • fetch.max.bytes:默認 Default: 52428800(50 m)。消費者獲取伺服器端一批消息最大的字節數。如果伺服器端一批次的數據大於該值(50m)仍然可以拉取回來這批數據,因此,這不是一個絕、對最大值。一批次的大小受 message.max.bytes (broker config)or max.message.bytes (topic config)影響。
  • max.poll.records:一次 poll 拉取數據返回消息的最大條數,默認是 500 條
  1. 優化消費者代碼處理的邏輯

總結

本文總結了Kafka為什麼快的原因,4個關鍵字,磁碟順序讀寫,頁緩存技術,零拷貝技術,Kafka本身分區機制和批量操作。我們抓住這4個關鍵字,有點到面地和面試官娓娓道來。

Kafka 在性能上確實是一騎絕塵,但在消息選型過程中,我們不僅僅要參考其性能,還有從功能性上來考慮,例如 RocketMQ 提供了豐富的消息檢索功能、事務消息、消息消費重試、定時消息等。

通常在大數據、流式處理場景基本選用 Kafka,業務處理相關選擇 RocketMQ更佳。

關鍵字: