之前在項(xiàng)目中用到了kafka做消息傳遞拖陆,一直聽說過kafka的性能非常高障本,這里總結(jié)下kafka為了實(shí)現(xiàn)高性能io的做了哪些設(shè)計(jì)用了什么方式教届。以對(duì)自己今后進(jìn)行高性能服務(wù)設(shè)計(jì)作參考。
1.批量消息處理
kafka服務(wù)端在處理消息的時(shí)候驾霜,并不是生產(chǎn)者發(fā)送一條消息它處理一條案训,而是先攢一批消息然后一并進(jìn)行處理,而且在之后的消息刷盤和發(fā)送給消費(fèi)者粪糙,消息都是以一批的形式進(jìn)行處理强霎。這樣的好處就是可以明顯降低請(qǐng)求數(shù),緩解broker的壓力蓉冈,提高處理效率城舞,但是也存在消息發(fā)送不及時(shí)的缺點(diǎn),即這種方式適用于對(duì)實(shí)時(shí)性要求不是特別高的系統(tǒng)
2.順序磁盤io
眾所周知磁盤io涉及到磁盤機(jī)械臂的機(jī)械運(yùn)動(dòng)寞酿,性能本身就不算特別高家夺,如果還是隨機(jī)磁盤io操作的話,性能就會(huì)大大降低伐弹,但是為了持久化消息以保證消息不丟失拉馋,又必須將消息寫入磁盤,所以這里kafka在往磁盤上寫消息時(shí)都是順序?qū)懖液茫粋€(gè)文件寫滿了再開啟一個(gè)新的文件繼續(xù)寫煌茴,這樣順序io就避免了隨機(jī)io需要先尋址再進(jìn)行讀寫導(dǎo)致的性能低下,消費(fèi)的時(shí)候讀消息也是從某個(gè)位置開始順序讀出來日川。
3.利用PageCache緩存
上面提到了磁盤io的性能很低蔓腐,而才內(nèi)存中進(jìn)行讀寫則非常快逗鸣,而kafka就利用了操作系統(tǒng)中的PageCache技術(shù)來利用內(nèi)存加速消息的讀寫合住。PageCache是大部分操作系統(tǒng)都有的特性,即我們?cè)谄綍r(shí)程序中對(duì)磁盤里的文件進(jìn)行讀寫時(shí)撒璧,并不是直接對(duì)磁盤進(jìn)行操作透葛,操作系統(tǒng)會(huì)將文件的一部分拷貝到內(nèi)存中,我們則是對(duì)內(nèi)存中的緩存進(jìn)行讀寫卿樱,然后PageCache再一批一批將內(nèi)存中的修改寫入磁盤僚害。
而在PageCache中進(jìn)行讀寫有兩種情況,一種是PageCache中有數(shù)據(jù),則可以直接進(jìn)行讀寫萨蚕,第二種是沒有數(shù)據(jù)靶草,則此時(shí)會(huì)發(fā)生一次缺頁中斷,操作系統(tǒng)會(huì)進(jìn)行一次磁盤io將文件內(nèi)容讀到PageCache中岳遥,一般來說應(yīng)用程序用過的PageCache不會(huì)立刻被操作系統(tǒng)清理奕翔,而是會(huì)使用LRU算法后續(xù)慢慢清理。而kafka由于一般剛寫入的消息基本上會(huì)立刻被消費(fèi)浩蓉,所以PageCache的命中率非常高派继,非常好的利用到了PageCache的特性。
4.零拷貝技術(shù)
一般來說一條消息從文件讀出來發(fā)送到消費(fèi)者是這樣一個(gè)流程:
a.讀取文件中的消息到內(nèi)存
b.將內(nèi)存中的消息發(fā)送到網(wǎng)絡(luò)端
而在這個(gè)過程中2-3次數(shù)據(jù)拷貝捻艳,比如從文件讀到PageCache中(如果命中PageCache則不用這步操作)驾窟,從PageCache拷貝到應(yīng)用程序內(nèi)存空間,從內(nèi)存空間拷貝到socket緩沖區(qū)认轨,而kakfa利用系統(tǒng)中的一個(gè)系統(tǒng)調(diào)用绅络,直接將消息從PageCache拷貝到socket中,減少一次數(shù)據(jù)拷貝嘁字,而且這種方式不用拷貝到應(yīng)用程序的內(nèi)存空間恩急,dma控制器可以直接完成數(shù)據(jù)復(fù)制,速度更快