網(wǎng)易二面:Kafka為什么吞吐量大、速度快?
來源:cnblogs.com/starluke/p/12558952.html
Kafka是大數(shù)據(jù)領(lǐng)域無處不在的消息中間件,目前廣泛使用在企業(yè)內(nèi)部的實時數(shù)據(jù)管道,并幫助企業(yè)構(gòu)建自己的流計算應(yīng)用程序。
Kafka雖然是基于磁盤做的數(shù)據(jù)存儲,但卻具有高性能、高吞吐、低延時的特點,其吞吐量動輒幾萬、幾十上百萬。
但是很多使用過Kafka的人,經(jīng)常會被問到這樣一個問題,Kafka為什么速度快,吞吐量大;大部分被問的人都是一下子就懵了,或者是只知道一些簡單的點,本文就簡單的介紹一下Kafka為什么吞吐量大,速度快。
一、順序讀寫
這里給出著名學(xué)術(shù)期刊 ACM Queue 上的性能對比圖:


上圖就展示了Kafka是如何寫入數(shù)據(jù)的, 每一個Partition其實都是一個文件 ,收到消息后Kafka會把數(shù)據(jù)插入到文件末尾(虛框部分)。
這種方法有一個缺陷—— 沒有辦法刪除數(shù)據(jù) ,所以Kafka是不會刪除數(shù)據(jù)的,它會把所有的數(shù)據(jù)都保留下來,每個消費者(Consumer)對每個Topic都有一個offset用來表示 讀取到了第幾條數(shù)據(jù) 。

如果不刪除硬盤肯定會被撐滿,所以Kakfa提供了兩種策略來刪除數(shù)據(jù)。一是基于時間,二是基于partition文件大小。具體配置可以參看它的配置文檔。
二、Page Cache
為了優(yōu)化讀寫性能,Kafka利用了操作系統(tǒng)本身的Page Cache,就是利用操作系統(tǒng)自身的內(nèi)存而不是JVM空間內(nèi)存。這樣做的好處有:
避免Object消耗:如果是使用 Java 堆,Java對象的內(nèi)存消耗比較大,通常是所存儲數(shù)據(jù)的兩倍甚至更多。
避免GC問題:隨著JVM中數(shù)據(jù)不斷增多,垃圾回收將會變得復(fù)雜與緩慢,使用系統(tǒng)緩存就不會存在GC問題
相比于使用JVM或in-memory cache等數(shù)據(jù)結(jié)構(gòu),利用操作系統(tǒng)的Page Cache更加簡單可靠。
首先,操作系統(tǒng)層面的緩存利用率會更高,因為存儲的都是緊湊的字節(jié)結(jié)構(gòu)而不是獨立的對象。
其次,操作系統(tǒng)本身也對于Page Cache做了大量優(yōu)化,提供了 write-behind、read-ahead以及flush等多種機制。
再者,即使服務(wù)進程重啟,系統(tǒng)緩存依然不會消失,避免了in-process cache重建緩存的過程。
通過操作系統(tǒng)的Page Cache,Kafka的讀寫操作基本上是基于內(nèi)存的,讀寫速度得到了極大的提升。
三、零拷貝
linux操作系統(tǒng) “零拷貝” 機制使用了sendfile方法, 允許操作系統(tǒng)將數(shù)據(jù)從Page Cache 直接發(fā)送到網(wǎng)絡(luò),只需要最后一步的copy操作將數(shù)據(jù)復(fù)制到 NIC 緩沖區(qū), 這樣避免重新復(fù)制數(shù)據(jù) 。示意圖如下:

當Kafka客戶端從服務(wù)器讀取數(shù)據(jù)時,如果不使用零拷貝技術(shù),那么大致需要經(jīng)歷這樣的一個過程:
應(yīng)用程序(也就是Kafka)從內(nèi)核空間的讀緩沖區(qū)將數(shù)據(jù)拷貝到用戶空間的緩沖區(qū)中。
應(yīng)用程序?qū)?shù)據(jù)從用戶空間的緩沖區(qū)再寫回到內(nèi)核空間的socket緩沖區(qū)中。
操作系統(tǒng)將socket緩沖區(qū)中的數(shù)據(jù)拷貝到NIC緩沖區(qū)中,然后通過網(wǎng)絡(luò)發(fā)送給客戶端。


可見,這里的零拷貝并非指一次拷貝都沒有,而是避免了在內(nèi)核空間和用戶空間之間的拷貝。如果真是一次拷貝都沒有,那么數(shù)據(jù)發(fā)給客戶端就沒了不是?不過,光是省下了這一步就可以帶來性能上的極大提升。
四、分區(qū)分段+索引
五、批量讀寫
Kafka數(shù)據(jù)讀寫也是批量的而不是單條的。
除了利用底層的技術(shù)外,Kafka還在應(yīng)用程序?qū)用嫣峁┝艘恍┦侄蝸硖嵘阅?。最明顯的就是使用批次。在向Kafka寫入數(shù)據(jù)時,可以啟用批次寫入,這樣可以避免在網(wǎng)絡(luò)上頻繁傳輸單個消息帶來的延遲和帶寬開銷。假設(shè)網(wǎng)絡(luò)帶寬為10MB/S,一次性傳輸10MB的消息比傳輸1KB的消息10000萬次顯然要快得多。
六、批量壓縮
在很多情況下,系統(tǒng)的瓶頸不是CPU或磁盤,而是網(wǎng)絡(luò)IO,對于需要在廣域網(wǎng)上的數(shù)據(jù)中心之間發(fā)送消息的數(shù)據(jù)流水線尤其如此。進行數(shù)據(jù)壓縮會消耗少量的CPU資源,不過對于kafka而言,網(wǎng)絡(luò)IO更應(yīng)該需要考慮。
1、2019 年 9 月全國程序員工資統(tǒng)計,你是什么水平?
3、從零開始搭建創(chuàng)業(yè)公司后臺技術(shù)棧
5、37歲程序員被裁,120天沒找到工作,無奈去小公司,結(jié)果懵了...
6、滴滴業(yè)務(wù)中臺構(gòu)建實踐,首次曝光
