Kafka如何實現(xiàn)高性能IO?
一利职、使用批量消息提升服務端處理能力
雖然kafka的sdk提供了單條消息發(fā)送趣效,但實際上,Kafka 的客戶端 SDK 在實現(xiàn)消息發(fā)送邏輯的時候猪贪,采用了異步批量發(fā)送的機制跷敬;
當你調(diào)用 send() 方法發(fā)送一條消息之后,無論你是同步發(fā)送還是異步發(fā)送热押,Kafka 都不會立即就把這條消息發(fā)送出去西傀。它會先把這條消息斤寇,存放在內(nèi)存中緩存起來,然后選擇合適的時機把緩存中的所有消息組成一批拥褂,一次性發(fā)給 Broker
在 Kafka 的服務端批消息都不會被解開娘锁,一直是作為一條“批消息”來進行處理的
在消費時,消息同樣是以批為單位進行傳遞的饺鹃,Consumer 從 Broker 拉到一批消息后莫秆,在客戶端把批消息解開,再一條一條交給用戶代碼處理
二悔详、使用順序讀寫提升磁盤 IO 性能
順序讀寫相比隨機讀寫省去了大部分的尋址時間镊屎,它只要尋址一次,就可以連續(xù)地讀寫下去茄螃,所以說缝驳,性能要比隨機讀寫要好很多
Kafka 就是充分利用了磁盤的這個特性。它的存儲設計非常簡單归苍,對于每個分區(qū)用狱,它把從 Producer 收到的消息,順序地寫入對應的 log 文件中霜医,一個文件寫滿了齿拂,就開啟一個新的文件這樣順序?qū)懴氯ァOM的時候肴敛,也是從某個全局的位置開始署海,也就是某一個 log 文件中的某個位置開始,順序地把消息讀出來
三医男、利用緩存頁PageCache加速消息讀寫
PageCache
PageCache 是現(xiàn)代操作系統(tǒng)都具有的一項基本特性砸狞。通俗地說,PageCache 就是操作系統(tǒng)在內(nèi)存中給磁盤上的文件建立的緩存镀梭。無論我們使用什么語言編寫的程序刀森,在調(diào)用系統(tǒng)的 API 讀寫文件的時候,并不會直接去讀寫磁盤上的文件报账,應用程序?qū)嶋H操作的都是 PageCache研底,也就是文件在內(nèi)存中緩存的副本。
應用程序?qū)懭胛募?/p>
操作系統(tǒng)會先把數(shù)據(jù)寫入到內(nèi)存中的 PageCache透罢,然后再一批一批地寫到磁盤上
應用程序讀取文件
有兩種情況:一種是 PageCache 中有數(shù)據(jù)榜晦,那就直接讀取羽圃;另一種情況是乾胶,PageCache 中沒有數(shù)據(jù),這時候操作系統(tǒng)會引發(fā)一個缺頁中斷,應用程序的讀取線程會被阻塞识窿,操作系統(tǒng)把數(shù)據(jù)從文件中復制到 PageCache 中斩郎,然后應用程序再從 PageCache 中繼續(xù)把數(shù)據(jù)讀出來,這時會真正讀一次磁盤上的文件喻频,這個讀的過程就會比較慢缩宜。
PageCache清理機制
用戶的應用程序在使用完某塊 PageCache 后,操作系統(tǒng)并不會立刻就清除這個 PageCache半抱,而是盡可能地利用空閑的物理內(nèi)存保存這些 PageCache脓恕,除非系統(tǒng)內(nèi)存不夠用,操作系統(tǒng)才會清理掉一部分 PageCache窿侈。清理的策略一般是 LRU 或它的變種算法,它保留 PageCache 的邏輯是:優(yōu)先保留最近一段時間最常使用的那些 PageCache
kafka讀寫消息文件
kafka充分利用了 PageCache 的特性秋茫。一般來說史简,消息剛剛寫入到服務端就會被消費,按照 LRU 的“優(yōu)先清除最近最少使用的頁”這種策略肛著,讀取的時候圆兵,對于這種剛剛寫入的 PageCache,命中的幾率會非常高枢贿。也就是說殉农,大部分情況下,kafka消費讀消息都會命中 PageCache局荚,帶來的好處有兩個:一個是讀取的速度會非吵剩快,另外一個是耀态,給寫入消息讓出磁盤的 IO 資源轮傍,間接也提升了寫入的性能。
四首装、ZeroCopy:零拷貝技術(shù)
在消息服務端處理消費的大致過程:
- 1创夜、從文件中找到消息數(shù)據(jù),讀到內(nèi)存中仙逻;
- 2驰吓、把消息通過網(wǎng)絡發(fā)給客戶端。
這個過程中系奉,數(shù)據(jù)實際上做了 2 次或者 3 次復制:
- 1檬贰、從文件復制數(shù)據(jù)到 PageCache 中,如果命中 PageCache喜最,這一步可以省掉偎蘸;
- 2、從 PageCache 復制到應用程序的內(nèi)存空間中,也就是我們可以操作的對象所在的內(nèi)存迷雪;
- 3限书、從應用程序的內(nèi)存空間復制到 Socket 的緩沖區(qū),這個過程就是我們調(diào)用網(wǎng)絡應用框架的 API 發(fā)送數(shù)據(jù)的過程章咧。
Kafka 使用零拷貝技術(shù)可以把這個復制次數(shù)減少一次倦西,上面的 2、3 步驟兩次復制合并成一次復制赁严。直接從 PageCache 中把數(shù)據(jù)復制到 Socket 緩沖區(qū)中扰柠,這樣不僅減少一次數(shù)據(jù)復制,更重要的是疼约,由于不用把數(shù)據(jù)復制到用戶內(nèi)存空間卤档,DMA 控制器可以直接完成數(shù)據(jù)復制,不需要 CPU 參與程剥,速度更快