Kafka-生產者-BufferPool

? ? 注:本文依賴于kafka-0.10.0.1-src

? ? 我們都知道kafka生產者send一條記錄(record)后并沒有直接發(fā)送到kafka服務端,而是先將它保存到內存(RecordAccumulator)中,用于壓縮之后批量發(fā)送,這里內存的創(chuàng)建和釋放是比較消耗資源的,為了實現(xiàn)內存的高效利用,基本上每個成熟的框架或者工具都有一套內存管理機制,kafka的生產者使用BufferPool來實現(xiàn)內存(Java NIO的ByteBuffer)的復用。

? ? BufferPool是什么呢?如圖1:

圖1

? ? 圖1包含兩個部分,紅色和綠色的總和代表BufferPool的總量,用totalMemory表示(由buffer.memory配置);綠色代表可使用的空間,它又包括兩個部分:上半部分代表未申請未使用的部分,用availableMemory表示;下半部分代表已經申請但沒有使用的部分,用一個ByteBuffer隊列(Deque<ByteBuffer>)表示,我們稱這個隊列為free,隊列中的ByteBuffer的大小用poolableSize表示(由batch.size配置)。

? ? 下圖2總結了從BufferPool中分配固定size大小的內存的步驟:

圖2

? ? 從圖2可以看出申請size大小的內存有這么幾種結束方式(紅色框部分),1、異常結束,比如申請的內存過大超過總量限定2、直接用隊列中的ByteBuffer分配內存;3、用avaliableMemory分配內存。

? ? 藍色框內的為大多數的內存分配方式,就是從隊列中直接拿想要的ByteBuffer,也是kafka希望的分配方式;黃色的框為分配內存時隊列中的內存不符合其分配的條件(隊列為空或大小不匹配),從availableMemory中分配;綠色框為當前內存池中內存不足時阻塞等待的情況,具體就是有一個累加器accumulated,如果累加器沒有累加到size大小,說明還沒有足夠的內存釋放出來,所以就會阻塞等待內存釋放,內存釋放之后會喚醒阻塞的線程,將可以分配的內存大小累加到累加器accumulated上,這樣直到累加器accumulated大小滿足size,就直接分配。這里面還有一個原則就是如果還沒給累加器accumulated累加過一次的話,也就是accumulated==0的時候,那么會優(yōu)先嘗試從隊列中獲取內存(有可能釋放的內存釋放到隊列中)。

? ? 釋放內存的話就比較簡單了,如果釋放的大小等于poolableSize的話,就把它放入free隊列,否則釋放到availableMemory中(availableMemory+=size)。所以只有固定大小的內存塊被釋放后才會進入池化列表,非常規(guī)釋放后只會增加可用內存大小。

? ? BufferPool是線程安全的,用一個ReentrantLock來保證,并且用一個Deque<Condition> waiters隊列來記錄申請不到足夠空間而阻塞的線程,此隊列中實際記錄的是阻塞線程對應的Condition對象,如圖3所示,將阻塞線程對應的Condition加入隊列,等待喚醒,喚醒的順序根據入隊順序決定(先進先出)。

圖3

? ? 總結:可以看到BufferPool只針對特定大小(poolableSize)的ByteBuffer進行管理,對于其它大小的并不會緩存進來。因此如果超大消息比較多(大于poolableSize),就不會很好的利用內存池,頻繁的申請回收內存效率會降低,并可能帶來Full GC或者Out Of Memory Error,這個時候就要調整好batch.size的配置了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 姓名:周小蓬 16019110037 轉載自:http://blog.csdn.net/YChenFeng/art...
    aeytifiw閱讀 34,743評論 13 425
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,868評論 18 139
  • 1.ios高性能編程 (1).內層 最小的內層平均值和峰值(2).耗電量 高效的算法和數據結構(3).初始化時...
    歐辰_OSR閱讀 29,547評論 8 265
  • 你走在前面,低頭,拔著手機 我在后面,喚你 你轉身,站定 ——我按下快門 完美 我一聲,你便懂 你一個動作 我全懂...
    我形我素閱讀 381評論 0 5
  • 從參加海選到復賽,已經過去兩周了,上周的忘詞真的很尷尬,真的很感謝兩位老師讓我晉級,我下次一定不辜負兩位老師對我的...
    逍遙如風閱讀 212評論 0 2