真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

kafka發(fā)送客戶端在高并發(fā)場(chǎng)景下如何保證不頻繁GC的

kafka發(fā)送客戶端在高并發(fā)場(chǎng)景下如何保證不頻繁GC的,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

10年積累的網(wǎng)站制作、成都做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有烏拉特后免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

最近看kafka源碼,著實(shí)被它的客戶端緩沖池技術(shù)優(yōu)雅到了。

注:用到的源碼來自kafka2.2.2版本。


背景

當(dāng)我們應(yīng)用程序調(diào)用kafka客戶端 producer發(fā)送消息的時(shí)候,在kafka客戶端內(nèi)部,會(huì)把屬于同一個(gè)topic分區(qū)的消息先匯總起來,形成一個(gè)batch。真正發(fā)往kafka服務(wù)器的消息都是以batch為單位的。如下圖所示:

kafka發(fā)送客戶端在高并發(fā)場(chǎng)景下如何保證不頻繁GC的

這么做的好處顯而易見??蛻舳撕头?wù)端通過網(wǎng)絡(luò)通信,這樣批量發(fā)送可以減少網(wǎng)絡(luò)帶來的性能開銷,提高吞吐量。

這個(gè)Batch的管理就非常值得探討了??赡苡腥藭?huì)說,這不簡(jiǎn)單嗎?用的時(shí)候分配一個(gè)塊內(nèi)存,發(fā)送完了釋放不就行了嗎。

kafka是用java語言編寫的(新版本大部分都是用java實(shí)現(xiàn)的了),用上面的方案就是使用的時(shí)候new一個(gè)空間然后賦值給一個(gè)引用,釋放的時(shí)候把引用置為null等JVM GC處理就可以了。

看起來似乎也沒啥問題。但是在并發(fā)量比較高的時(shí)候就會(huì)頻繁的進(jìn)行GC。我們都知道GC的時(shí)候有個(gè)stop the world,盡管最新的GC技術(shù)這個(gè)時(shí)間已經(jīng)非常短,依然有可能成為生產(chǎn)環(huán)境的性能瓶頸。

kafka的設(shè)計(jì)者當(dāng)然能考慮到這一層。下面我們就來學(xué)習(xí)下kafka是如何對(duì)batch進(jìn)行管理的。

 

緩沖池技術(shù)原理解析

kafka客戶端使用了緩沖池的概念,預(yù)先分配好真實(shí)的內(nèi)存塊,放在池子里。

每個(gè)batch其實(shí)都對(duì)應(yīng)了緩沖池中的一個(gè)內(nèi)存空間,發(fā)送完消息之后,batch不再使用了,就把內(nèi)存塊歸還給緩沖池。

聽起來是不是很耳熟???不錯(cuò),數(shù)據(jù)庫(kù)連接池,線程池等池化技術(shù)其實(shí)差不多都是這樣的原理。通過池化技術(shù)降低創(chuàng)建和銷毀帶來的開銷,提升執(zhí)行效率。

kafka發(fā)送客戶端在高并發(fā)場(chǎng)景下如何保證不頻繁GC的

代碼是最好的文檔,,下面我們就來擼下源碼。

我們擼代碼的步驟采用的是從上往下的原則,先帶你看看緩沖池在哪里使用,然后再深入到緩存池內(nèi)部深入分析。

下面的代碼做了一些刪減,值保留了跟本文相關(guān)的部分便于分析。

kafka發(fā)送客戶端在高并發(fā)場(chǎng)景下如何保證不頻繁GC的

kafka發(fā)送客戶端在高并發(fā)場(chǎng)景下如何保證不頻繁GC的

RecordAccumulator其實(shí)就是管理一個(gè)batch隊(duì)列,我們看到append方法實(shí)現(xiàn)其實(shí)是調(diào)用BufferPool的free方法申請(qǐng)(allocate)了一塊內(nèi)存空間(ByteBuffer), 然后把這個(gè)內(nèi)存空空間包裝成batch添加到隊(duì)列后面。

當(dāng)消息發(fā)送完成不在使用batch的時(shí)候,RecordAccumulator會(huì)調(diào)用deallocate方法歸還內(nèi)存,內(nèi)部其實(shí)是調(diào)用BufferPooldeallocate方法。

kafka發(fā)送客戶端在高并發(fā)場(chǎng)景下如何保證不頻繁GC的

很明顯,BufferPool就是緩沖池管理的類,也是我們今天要討論的重點(diǎn)。我們先來看看分配內(nèi)存塊的方法。

kafka發(fā)送客戶端在高并發(fā)場(chǎng)景下如何保證不頻繁GC的

首先整個(gè)方法是加鎖操作的,所以支持并發(fā)分配內(nèi)存。

邏輯是這樣的,當(dāng)申請(qǐng)的內(nèi)存大小等于poolableSize,則從緩存池中獲取。這個(gè)poolableSize可以理解成是緩沖池的頁(yè)大小,作為緩沖池分配的基本單位。從緩存池獲取其實(shí)就是從ByteBuffer隊(duì)列取出一個(gè)元素返回。

如果申請(qǐng)的內(nèi)存不等于特定的數(shù)值,則向非緩存池申請(qǐng)。同時(shí)會(huì)從緩沖池中取一些內(nèi)存并入到非緩沖池中。這個(gè)nonPooledAvailableMemory指的就是非緩沖池的可用內(nèi)存大小。非緩沖池分配內(nèi)存,其實(shí)就是調(diào)用ByteBuffer.allocat分配真實(shí)的JVM內(nèi)存。

kafka發(fā)送客戶端在高并發(fā)場(chǎng)景下如何保證不頻繁GC的

緩存池的內(nèi)存一般都很少回收。而非緩存池的內(nèi)存是使用后丟棄,然后等待GC回收。

繼續(xù)來看看batch釋放的代碼,

kafka發(fā)送客戶端在高并發(fā)場(chǎng)景下如何保證不頻繁GC的

很簡(jiǎn)單,也是分為兩種情況。要么直接歸還緩沖池,要么就是更新非緩沖池部分的可以內(nèi)存。然后通知等待隊(duì)列里的第一個(gè)元素。

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。


網(wǎng)站欄目:kafka發(fā)送客戶端在高并發(fā)場(chǎng)景下如何保證不頻繁GC的
分享地址:http://weahome.cn/article/iisshc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部