前言:? Kafka雖然是基于磁盤做的數(shù)據(jù)存儲策精,但卻具有高性能舰始、高吞吐、低延時的特點咽袜,其吞吐量動輒幾萬丸卷、幾十上百萬⊙玻總結(jié)起來大致就5個原因谜嫉,順序讀寫、零拷貝凹联、分區(qū)沐兰、批量發(fā)送、數(shù)據(jù)壓縮蔽挠。
1住闯、順序讀寫
????眾所周知Kafka是將消息記錄持久化到本地磁盤中的,一般人會認為磁盤讀寫性能差澳淑,可能會對Kafka性能如何保證提出質(zhì)疑比原。實際上不管是內(nèi)存還是磁盤,快或慢關(guān)鍵在于尋址的方式杠巡,磁盤分為順序讀寫與隨機讀寫量窘,內(nèi)存也一樣分為順序讀寫與隨機讀寫∏庥担基于磁盤的隨機讀寫確實很慢蚌铜,但磁盤的順序讀寫性能卻很高,一般而言要高出磁盤隨機讀寫三個數(shù)量級嫩海,一些情況下磁盤順序讀寫性能甚至要高于內(nèi)存隨機讀寫冬殃。
? ??Kafka的message是不斷追加到本地磁盤文件末尾的,而不是隨機的寫入出革,這使得Kafka寫入吞吐量得到了顯著提升造壮。?
? ??這種方法有一個缺陷—— 沒有辦法刪除數(shù)據(jù) ,所以Kafka是不會刪除數(shù)據(jù)的骂束,它會把所有的數(shù)據(jù)都保留下來耳璧,每個消費者(Consumer)對每個Topic都有一個offset用來表示 讀取到了第幾條數(shù)據(jù) 。
2展箱、零拷貝
????linux操作系統(tǒng) “零拷貝” 機制使用了sendfile方法旨枯, 允許操作系統(tǒng)將數(shù)據(jù)從Page Cache 直接發(fā)送到網(wǎng)絡(luò),只需要最后一步的copy操作將數(shù)據(jù)復(fù)制到 NIC 緩沖區(qū)混驰, 這樣避免重新復(fù)制數(shù)據(jù) 攀隔。示意圖如下:
? ??通過這種 “零拷貝” 的機制皂贩,Page Cache 結(jié)合 sendfile 方法,Kafka消費端的性能也大幅提升昆汹。這也是為什么有時候消費端在不斷消費數(shù)據(jù)時明刷,我們并沒有看到磁盤io比較高,此刻正是操作系統(tǒng)緩存在提供數(shù)據(jù)满粗。
3辈末、分區(qū)
????Kafka的message是按topic分類存儲的,topic中的數(shù)據(jù)又是按照一個一個的partition即分區(qū)存儲到不同broker節(jié)點映皆。每個partition對應(yīng)了操作系統(tǒng)上的一個文件夾挤聘,partition實際上又是按照segment分段存儲的。這也非常符合分布式系統(tǒng)分區(qū)分桶的設(shè)計思想捅彻。
? ? 通過這種分區(qū)分段的設(shè)計组去,Kafka的message消息實際上是分布式存儲在一個一個小的segment中的,每次文件操作也是直接操作的segment步淹。為了進一步的查詢優(yōu)化从隆,Kafka又默認為分段后的數(shù)據(jù)文件建立了索引文件,就是文件系統(tǒng)上的.index文件贤旷。這種分區(qū)分段+索引的設(shè)計广料,不僅提升了數(shù)據(jù)讀取的效率,同時也提高了數(shù)據(jù)操作的并行度幼驶。
4、批量讀寫
????Kafka數(shù)據(jù)讀寫也是批量的而不是單條的韧衣。
? ? 除了利用底層的技術(shù)外盅藻,Kafka還在應(yīng)用程序?qū)用嫣峁┝艘恍┦侄蝸硖嵘阅堋W蠲黠@的就是使用批次畅铭。在向Kafka寫入數(shù)據(jù)時氏淑,可以啟用批次寫入,這樣可以避免在網(wǎng)絡(luò)上頻繁傳輸單個消息帶來的延遲和帶寬開銷硕噩。假設(shè)網(wǎng)絡(luò)帶寬為10MB/S假残,一次性傳輸10MB的消息比傳輸1KB的消息10000萬次顯然要快得多。
5炉擅、批量壓縮
? ???在很多情況下辉懒,系統(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)如果每個消息都壓縮快鱼,但是壓縮率相對很低颠印,所以Kafka使用了批量壓縮纲岭,即將多個消息一起壓縮而不是單個消息壓縮
? ? 2)Kafka允許使用遞歸的消息集合,批量的消息可以通過壓縮的形式傳輸并且在日志中也可以保持壓縮格式线罕,直到被消費者解壓縮
? ? 3)Kafka支持多種壓縮協(xié)議止潮,包括Gzip和Snappy壓縮協(xié)議
總結(jié):Kafka速度的秘訣在于,它把所有的消息都變成一個批量的文件钞楼,并且進行合理的批量壓縮喇闸,減少網(wǎng)絡(luò)IO損耗,通過mmap提高I/O速度窿凤,寫入數(shù)據(jù)的時候由于單個Partion是末尾添加所以速度最優(yōu)仅偎;讀取數(shù)據(jù)的時候配合sendfile直接暴力輸出。