您好,登錄后才能下訂單哦!
問(wèn)題背景
項(xiàng)目中將Kafka接口進(jìn)行RESTful封裝,在使用RESTful接口進(jìn)行性能測(cè)試時(shí),發(fā)現(xiàn)Topic數(shù)增多后,開(kāi)啟SSL與非SSL進(jìn)行測(cè)試,發(fā)現(xiàn)開(kāi)啟SSL后性能下降得厲害。例如600個(gè)Topic總數(shù)每個(gè)Topic3分區(qū)3副本的場(chǎng)景下,使用1200個(gè)線程只發(fā)送10個(gè)Topic,開(kāi)啟SSL的TPS只有3100,但是不開(kāi)啟SSL性能達(dá)到11000。
其中測(cè)試客戶端會(huì)啟動(dòng)多個(gè)線程,每個(gè)線程采用同步發(fā)送的方式調(diào)用RESTful API發(fā)送,即每次發(fā)送成功一條后才發(fā)送下一條。 客戶端會(huì)根據(jù)發(fā)送線程在Topic數(shù)之間進(jìn)行均分,例如1200個(gè)線程發(fā)送10個(gè)Topic,則每個(gè)Topic同時(shí)有120個(gè)線程進(jìn)行發(fā)送。
定位與分析過(guò)程
1.SSL性能下降
1.定位分析
開(kāi)啟SSL是會(huì)導(dǎo)致性能下降的, 主要來(lái)自于CPU的耗時(shí)與JVM的具體實(shí)現(xiàn),參見(jiàn)Kafka官網(wǎng)的解釋:
從我們之前測(cè)試的結(jié)果來(lái)看,高可靠場(chǎng)景SSL性能下降并沒(méi)有太厲害(從2.3W TPS下降到2.1W TPS)。應(yīng)該是觸發(fā)了某些其他問(wèn)題。通過(guò)JStack查看啟動(dòng)SSL下的堆棧,發(fā)現(xiàn)存在一些發(fā)送線程被Block?。?/p>
這個(gè)堆棧里面做的事情,是來(lái)自于java.security.SecureRandom要產(chǎn)生隨機(jī)數(shù),采用”SHA1PRNG”算法。在sun/oracle的jdk里,這個(gè)隨機(jī)算法的的實(shí)現(xiàn)在底層依賴到操作系統(tǒng)提供的隨機(jī)數(shù)據(jù),默認(rèn)用的是/dev/random,在讀取時(shí),/dev/random設(shè)備會(huì)返回小于熵池噪聲總數(shù)的隨機(jī)字節(jié)。/dev/random可生成高隨機(jī)性的公鑰或一次性密碼本。若熵池空了,對(duì)/dev/random的讀操作將會(huì)被阻塞,直到收集到了足夠的環(huán)境噪聲為止。這個(gè)問(wèn)題在網(wǎng)上也查到,主要是JDK提供的SecureRandom函數(shù)存在1個(gè)全局的鎖,在熵源不足且SSL線程多的時(shí)候很容易碰到這個(gè)問(wèn)題,具體見(jiàn):
https://github.com/netty/netty/issues/3639
http://bugs.java.com/view_bug.do?bug_id=6521844
2.解決措施
措施一:更新JDK
目前這個(gè)問(wèn)題是在OpenJDK 1.8中解決了,可以通過(guò)升級(jí)JDK到使用OpenJDK,但是這個(gè)方案不太好替換,并且OpenJDK和原來(lái)有什么不兼容還不清楚。
措施二:采用非阻塞的熵源: /dev/urandom
通過(guò)設(shè)置-Djava.security.egd=file:/dev/./urandom宏,隨機(jī)數(shù)時(shí)選擇/dev/urandom,它會(huì)重復(fù)地使用熵池中的數(shù)據(jù)以產(chǎn)生偽隨機(jī)數(shù)據(jù)避免阻塞,不過(guò)隨機(jī)安全性會(huì)降低。
2.Topic多情況下性能下降
1.定位分析
發(fā)現(xiàn)在Topic600個(gè)情況下,非SSL與SSL的時(shí)延其實(shí)差距并沒(méi)有原先發(fā)現(xiàn)的問(wèn)題那么大,以下是我們用SDK接口測(cè)試的時(shí)延數(shù)據(jù):
600個(gè) Topic總量下,400個(gè)線程同時(shí)發(fā)送10個(gè)Topic,非SSL與SSL時(shí)延對(duì)比:
可以看出時(shí)延差距在20%之內(nèi),主要的時(shí)延增加來(lái)自于Topic增多導(dǎo)致的。
為什么Topic增多會(huì)導(dǎo)致時(shí)延增多?針對(duì)這個(gè)問(wèn)題通過(guò)在程序進(jìn)行打點(diǎn)測(cè)試,以下是在不同的Topic數(shù)量情況下,針對(duì)10個(gè)Topic,總發(fā)送5000條消息的場(chǎng)景下,非SSL時(shí)延對(duì)比:
其中總時(shí)延 = 消息的待發(fā)送隊(duì)列等待時(shí)延 + 服務(wù)端處理平均時(shí)延 + 網(wǎng)絡(luò)發(fā)送與響應(yīng)時(shí)延。
從上面的表格可以看出基本上每個(gè)處理環(huán)節(jié)上都增加了時(shí)延4~5倍。為什么會(huì)出現(xiàn)這種情況?分析如下可能點(diǎn):
1、磁盤(pán)的寫(xiě)速度變慢
2、Server由于Topic多需要過(guò)濾信息變慢
3、復(fù)制處理在多Topic下變慢。即使無(wú)數(shù)據(jù),多Topic下復(fù)制線程也會(huì)一直發(fā)送空請(qǐng)求
4、Topic多資源占用大
通過(guò)逐一分析、排除與測(cè)試,主要原因還是在第三點(diǎn):服務(wù)端在復(fù)制處理在Topic數(shù)量多的情況下變慢導(dǎo)致的。
例如10個(gè)Topic的時(shí)候,如果用10個(gè)復(fù)制線程(目前性能測(cè)試就是配置10)用于副本復(fù)制,則每個(gè)復(fù)制線程會(huì)分配到1個(gè)Topic;而當(dāng)Topic有600個(gè)的時(shí)候,如果還是10個(gè)復(fù)制線程用于副本復(fù)制,則每個(gè)復(fù)制線程會(huì)分配到60個(gè)Topic。 如果此時(shí)只發(fā)送前10個(gè)Topic的時(shí)候,很有可能只有1個(gè)復(fù)制線程在工作,其他的復(fù)制線程由于分配到的Topic沒(méi)有數(shù)據(jù),基本處于空閑狀態(tài)。
2.解決措施
既然復(fù)制線程變慢,我們可以通過(guò)繼續(xù)增加復(fù)制線程的方式提高性能,在600個(gè)Topic場(chǎng)景只發(fā)送10個(gè)Topic場(chǎng)景下,我們把復(fù)制線程提升到60個(gè),這樣10個(gè)Topic能盡可能分配到不同的復(fù)制線程中,提高了復(fù)制的速度。以下是實(shí)際測(cè)試結(jié)果:
可以看到增加到60個(gè)fetch線程后,時(shí)延變?yōu)?00ms左右。同時(shí)原來(lái)的環(huán)境下,通過(guò)增加復(fù)制線程(修改配置num.replica.fetchers=60),在原環(huán)境下1200個(gè)發(fā)送線程即使啟動(dòng)SSL,性能也能達(dá)到11000+。
性能提升措施總結(jié)
RESTful API是同步接口,但是內(nèi)部使用的SDK接口是異步發(fā)送。根據(jù)高可靠場(chǎng)景下異步發(fā)送的能力能達(dá)到2W+ TPS來(lái)看,主要還是同步接口的并發(fā)壓力上不去導(dǎo)致的,可以通過(guò)以下措施來(lái)改進(jìn):
1、增加請(qǐng)求等待時(shí)間linger.ms
通過(guò)在客戶端增加參數(shù)linger.ms,使得每個(gè)請(qǐng)求回等待指定的時(shí)間后再發(fā)送,使得每個(gè)請(qǐng)求可以發(fā)送更多的數(shù)據(jù),即增加合包率。
2、增加同步發(fā)送對(duì)同1個(gè)Topic的并發(fā)數(shù)量
3、減少Topic的分區(qū)數(shù)
因?yàn)槟壳癛ESTful API并沒(méi)有用盡服務(wù)端的能力(1個(gè)分區(qū)的能力瓶頸還沒(méi)達(dá)到),默認(rèn)的3個(gè)分區(qū)是浪費(fèi)資源,并且會(huì)導(dǎo)致合包率降低,如果采用1個(gè)分區(qū),則同樣的壓力下,合包率能提升3倍,這樣性能也能提升。這個(gè)措施還可以支持更多的Topic數(shù)。
4、增加復(fù)制線程
5、考慮提供異步發(fā)送SDK接口
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。