MemStoreChunkPool&MSLAB提升HBASE GC性能

          

        Jvm使用過程中,一個比較重要的概念就是GC,Hbase是使用JAVA語言開發的,JVM的GC優化也是比較重要的一個優化方法。Hbase中對於寫的數據key/value大小不固定,有可能有很對比較小即大小的key/value,就有很大的概率產生jvm內存碎片問題。舉個例子:    

      當Jvm new一個2K大小的對象,JVM將無從heap分配它,因爲找不到連續可用的內存空間來容納這個對象,就算Heap當時還有500M的剩餘空間,也無能爲力。最終,JVM會選擇觸發Full GC重新壓縮內存使之連續,然後再分配。

即觸發Full GC,並不只有在內存滿或達到觸發比例的時候,還有可能是因爲內存碎片。

產生內存碎片的主要原因是:

  • 分配的大小不一。
  • 分配的空間不連續。

如何檢測因內存碎片觸發了Full GC?
通過啓動jvm時,添加 -XX:PrintFLSStatistics=1 參數來打印每次gc前後的Heap餘量。較大的餘量,可以懷疑Heap中存在內存碎片過多。
另外這篇blog有更詳細的圖文解釋:

http://www.cloudera.com/blog/2011/02/avoiding-full-gcs-in-hbase-with-memstore-local-allocation-buffers-part-2/


下圖是hbase在memstore產生jvm 碎片問題示意圖。


     

           Arena Allocation,是一種GC優化技術,它可以有效地減少因內存碎片導致的Full GC,從而提高系統的整體性能。MemStore-Local Allocation Buffers就是其在其在Hbase中的應用。

          MemStore-Local Allocation Buffers通過預先分配內存塊的方式解決了因爲內存碎片造成的Full GC問題,但是對於頻繁更新操作的時候,MemStore被flush到文件系統時沒有reference的chunk還是會觸發很多的Young GC。所以HBase-8163提出了MemStoreChunkPool的概念,也就是由HBase來管理一個ChunkPool用來存放chunk,不再依賴JVM的GC。這個ticket的本質也是由HBase進程來管理內存分配和重分配,不再依賴於Java GC。

       

MemStore-Local Allocation Buffer:

Ø每個MemStore都有一個MemStoreLAB實例

ØMemStoreLAB有一個2MB的curChunk,其nextFreeOffset爲0

Ø每次insert一個KV時,數據(byte[]數組)複製到curChunk,nextFreeOffset隨之增長

ØcurChunk滿了以後,重新分配一個2MB的Chunk

Ø上述操作採用compare-and-swap[cas],因此無需加鎖

優點: 

           a、原始插入的數據生命週期變短,就不用進入年老代

           b、可能進入年老代的Chunk是固定以2MB爲大小,消除碎片的煩惱

           c、 每個Chunk只可能屬於一個MemStore

           d、當MemStore刷到磁盤,Heap釋放的內存也是以2MB爲單位。

幾個重要的配置:

hbase.hregion.memstore.mslab.enabled

      是否啓用MSLAB,默認true

hbase.hregion.memstore.mslab.chunksize

         Chunk的尺寸,默認2MB

hbase.hregion.memstore.mslab.max.allocation

       MSLAB中單次分配內存的最大尺寸,默認256K,超過該尺寸的內存直接在Heap上分配。【當key/value大小大於256k,認爲不是內存碎片】。



MemStoreChunkPool 介紹:


Solution:
1.Create a chunk pool to manage the no-reference chunks, instead of being reclaimed by JVM
2.When a Chunk has no reference, put it back to the pool
3.The pool has a max capacity, it will skip the chunks when achieve the max size
4.When we need new Chunk to store KeyValue, get it from the pool if exists, else create new one by pool, so we could be able to reuse the old chunks


  


發佈了31 篇原創文章 · 獲贊 24 · 訪問量 72萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章