您好,登錄后才能下訂單哦!
背景:
1、緩存對于數據庫來說極其的重要
2、最理想的情況是,所有數據都能夠緩存到內存,這樣就不會有任何文件IO請求,讀寫性能必然會提升到極致。
3、我們并不需要將所有數據都緩存起來,根據二八法則,80%的業務請求都集中在20%的熱點數據上,
4、把20%的數據緩存起來,將這部分數據緩存起就可以極大地提升系統性能。
HBase在實現中提供了兩種緩存結構:MemStore和BlockCache。
MemStore
1、其中MemStore稱為寫緩存
2、HBase執行寫操作首先會將數據寫入MemStore,并順序寫入HLog,
//代碼中這樣,我們的理解為 先順序寫入HLog 再將數據寫入MemStore
3、等滿足一定條件后統一將MemStore中數據刷新到磁盤,這種設計可以極大地提升HBase的寫性能。
4、MemStore對于讀性能也至關重要,假如沒有MemStore,讀取剛寫入的數據就需要從文件中通過IO查找,這種代價顯然是昂貴的!
BlockCache
1、BlockCache稱為讀緩存
2、HBase會將一次文件查找的Block塊緩存到Cache中,以便后續同一請求或者鄰近數據查找請求,可以直接從內存中獲取,避免昂貴的IO操作。
簡單地回顧一下HBase中Block的概念
1、Block是HBase中最小的數據存儲單元,默認為64K,在建表語句中可以通過參數BlockSize指定。
2、HBase中Block分為四種類型:Data Block,Index Block,Bloom Block和Meta Block。
3、其中Data Block用于存儲實際數據,通常情況下每個Data Block可以存放多條KeyValue數據對;
4、Index Block和Bloom Block都用于優化隨機讀的查找路徑,
5、其中Index Block通過存儲索引數據加快數據查找,
6、而Bloom Block通過一定算法可以過濾掉部分一定不存在待查KeyValue的數據文件,減少不必要的IO操作;
7、Meta Block主要存儲整個HFile的元數據。
1、BlockCache是Region Server級別的,
2、一個Region Server只有一個Block Cache,在Region Server啟動的時候完成Block Cache的初始化工作。
3、到目前為止,HBase先后實現了3種Block Cache方案,LRUBlockCache是最初的實現方案,也是默認的實現方案;HBase 0.92版本實現了第二種方案SlabCache,見HBASE-4027;HBase 0.96之后官方提供了另一種可選方案BucketCache,見HBASE-7404。
4、這三種方案的不同之處在于對內存的管理模式,
5、其中LRUBlockCache是將所有數據都放入JVM Heap中,交給JVM進行管理。
6、SlabCache BucketCache 這兩種采用了不同機制將部分數據存儲在堆外,交給HBase自己管理。
7、這種演變過程是因為LRUBlockCache方案中JVM垃圾回收機制經常會導致程序長時間暫停,而采用堆外內存對數據進行管理可以有效避免這種情況發生。
LRUBlockCache //HBase默認的BlockCache實現方案
1、將內存從邏輯上分為了三塊:single-access區、mutil-access區、in-memory區,分別占到整個BlockCache大小的25%、50%、25%
2、一次隨機讀中,一個Block塊從HDFS中加載出來之后首先放入signle區,
3、后續如果有多次請求訪問到這塊數據的話,就會將這塊數據移到mutil-access區。
3、而in-memory區表示數據可以常駐內存,一般用來存放訪問頻繁、數據量小的數據,比如元數據,用戶也可以在建表的時候通過設置列族屬性IN-MEMORY= true將此列族放入in-memory區。 //這一部分參考 HBase - 建表語句解析 http://hbasefly.com/2016/03/23/hbase_create_table/ 中提到的 IN_MEMORY 參數
4、很顯然,這種設計策略類似于JVM中young區、old區以及perm區。
階段小結:
LRUBlockCache機制:類似于jvm的young區、old區以及perm區,他分為(single-access區、mutil-access區、in-memory區,分別占到整個BlockCache大小的25%、50%、25%)在一次隨機訪問數據的時候從hdfs加載出來,放到single-access區,后續如果有多次請求這塊的數據,就會放到 mutil-access區 而in-memory區表示數據可以常駐內存,一般用來存放訪問頻繁、數據量小的數據,比如元數據。
//當BlockCache總量達到一定閾值之后就會啟動淘汰機制,最少使用的Block會被置換出來,為新加載的Block預留空間。
缺點:使用LRUBlockCache緩存機制會因為CMS GC策略導致內存碎片過多,從而可能引發臭名昭著的Full GC,觸發可怕的’stop-the-world’暫停,嚴重影響上層業務
那CMS GC策略如何導致內存碎片過多?內存碎片過多如何觸發Full GC?請關注博主另一篇博客。
SlabCache //已經被淘汰了
1、為了解決LRUBlockCache方案中因為JVM垃圾回收導致的服務中斷,SlabCache方案使用Java NIO DirectByteBuffer技術實現了堆外內存存儲,不再由JVM管理數據內存。
2、默認情況下,系統在初始化的時候會分配兩個緩存區,分別占整個BlockCache大小的80%和20%,每個緩存區分別存儲固定大小的Block塊,
3、其中前者主要存儲小于等于64K大小的Block,后者存儲小于等于128K Block,如果一個Block太大就會導致兩個區都無法緩存。
4、和LRUBlockCache相同,SlabCache也使用Least-Recently-Used算法對過期Block進行淘汰。
5、和LRUBlockCache不同的是,SlabCache淘汰Block的時候只需要將對應的bufferbyte標記為空閑,后續cache對其上的內存直接進行覆蓋即可。
SlabCache 和 DoubleBlockCache 缺點為:
線上集群環境中,不同表不同列族設置的BlockSize都可能不同,很顯然,默認只能存儲兩種固定大小Block的SlabCache方案不能滿足部分用戶場景,
因此HBase實際實現中將SlabCache和LRUBlockCache搭配使用,稱為DoubleBlockCache。
1、DoubleBlockCache方案有很多弊端。比如SlabCache設計中固定大小內存設置會導致實際內存使用率比較低,
2、而且使用LRUBlockCache緩存Block依然會因為JVM GC產生大量內存碎片。
3、因此在HBase 0.98版本之后,該方案已經被不建議使用。
階段小結:
SlabCache:實現的是堆外內存存儲,不在由JVM管理數據內存。
DoubleBlockCache:因此HBase實際實現中將SlabCache和LRUBlockCache搭配使用,稱DoubleBlockCache。
為什么要搭配使用呢?或者說是SlabCache的缺點
1、線上集群環境中,不同表不同列族設置的BlockSize都可能不同,很顯然,默認只能存儲兩種固定大小Block的SlabCache方案不能滿足部分用戶場景,比如用戶設置BlockSize = 256K,簡單使用SlabCache方案就不能達到這部分Block緩存的目的。
2、一次隨機讀中,一個Block塊從HDFS中加載出來之后會在兩個Cache中分別存儲一份;緩存讀時首先在LRUBlockCache中查找,如果Cache Miss再在SlabCache中查找,此時如果命中再將該Block放入LRUBlockCache中。
缺點:
DoubleBlockCache方案有很多弊端。比如SlabCache設計中固定大小內存設置會導致實際內存使用率比較低,而且使用LRUBlockCache緩存Block依然會因為JVM GC產生大量內存碎片。因此在HBase 0.98版本之后,該方案已經被不建議使用。
//已經淘汰了
BucketCache //阿里設計出來的 cdh用的這種 //可以參考:hbase針對fullgc所做的優化(Memstore所作的優化 針對BlockCache所作優化):https://blog.51cto.com/12445535/2373223
1、SlabCache方案在實際應用中并沒有很大程度改善原有LRUBlockCache方案的GC弊端,還額外引入了諸如堆外內存使用率低的缺陷。然而它的設計并不是一無是處,至少在使用堆外內存這個方面給予了阿里大牛們很多啟發。站在SlabCache的肩膀上,他們開發了BucketCache緩存方案并貢獻給了社區。
2、實際實現中,HBase將BucketCache和LRUBlockCache搭配使用,稱為CombinedBlockCache。
3、和DoubleBlockCache不同,系統在LRUBlockCache中主要存儲Index Block和Bloom Block,而將Data Block存儲在BucketCache中
4、因此一次隨機讀需要首先在LRUBlockCache中查到對應的Index Block,然后再到BucketCache查找對應數據塊。BucketCache通過更加合理的設計修正了SlabCache的弊端,極大降低了JVM GC對業務請求的實際影響,
5、但也存在一些問題,比如使用堆外內存會存在拷貝內存的問題,一定程度上會影響讀寫性能。當然,在后來的版本中這個問題也得到了解決,
優點:
而Bucket Cache緩存機制因為在初始化的時候就申請了一片固定大小的內存作為緩存,緩存淘汰不再由 JVM管理,數據Block的緩存操作只是對這片空間的訪問和覆蓋,因而大大減少了內存碎片的出現,降低了Full GC發生的頻率。//Bucket Cache 緩存淘汰不再由 JVM管理 降低了Full GC發生的頻率。
Bucket Cache 緩存 中有3中模式 heap模式和offheap模式 file模式
offheap模式因為內存屬于操作系統,所以基本不會產生CMS GC,也就在任何情況下都不會因為內存碎片導致觸發Full GC。
LRUBlockCache //升入了解
1、它使用一個ConcurrentHashMap管理BlockKey到Block的映射關系,
2、緩存Block只需要將BlockKey和對應的Block放入該HashMap中,查詢緩存就根據BlockKey從HashMap中獲取即可。
3、同時該方案采用嚴格的LRU淘汰算法,當Block Cache總量達到一定閾值之后就會啟動淘汰機制,最近最少使用的Block會被置換出來。在具體的實現細節方面,需要關注三點:
緩存分層策略
//將整個BlockCache分為三個部分:single-access、mutil-access和inMemory。需要特別注意的是,HBase系統元數據存放在InMemory區,因此設置數據屬性InMemory = true需要非常謹慎,確保此列族數據量很小且訪問頻繁,否則有可能會將hbase.meta元數據擠出內存,嚴重影響所有業務性能。
LRU淘汰算法實現
BucketCache //升入了解概念 見博客 cdh默認是這種緩存模式
//它沒有使用JVM 內存管理算法來管理緩存,而是自己對內存進行管理,因此不會因為出現大量碎片導致Full GC的情況發生。
內存組織形式
Block緩存寫入、讀取流程
BucketCache工作模式
BucketCache配置使用 //重點 //cdh用的這種模式
//
BucketCache 的總大小,以 MB 為單位。要配置的大小取決于可供 HBase 使用的內存量或本地 SSD 的大小。如果將 hbase.bucketcache.ioengine 設為“offheap”,則 BucketCache 會消耗 Java 的直接內存中的已配置內存量。
hbase.bucketcache.size = 1M
提示:
其中heap模式和offheap模式都使用內存作為最終存儲介質,內存分配查詢也都使用Java NIO ByteBuffer技術,不同的是,heap模式分配內存會調用byteBuffer.allocate方法,從JVM提供的heap區分配,而后者會調用byteBuffer.allocateDirect方法,直接從操作系統分配。
這兩種內存分配模式會對HBase實際工作性能產生一定的影響。影響最大的無疑是GC ,相比heap模式,offheap模式因為內存屬于操作系統,所以基本不會產生CMS GC,也就在任何情況下都不會因為內存碎片導致觸發Full GC。
除此之外,在內存分配以及讀取方面,兩者性能也有不同,比如,內存分配時heap模式需要首先從操作系統分配內存再拷貝到JVM heap,相比offheap直接從操作系統分配內存更耗時;但是反過來,讀取緩存時heap模式可以從JVM heap中直接讀取,而offheap模式則需要首先從操作系統拷貝到JVM heap再讀取,顯得后者更費時。
file模式和前面兩者不同,它使用Fussion-IO或者SSD等作為存儲介質,相比昂貴的內存,這樣可以提供更大的存儲容量,因此可以極大地提升緩存命中率。
提示:
LRUBlockCache
SlabCache
DoubleBlockCache:因此HBase實際實現中將SlabCache和LRUBlockCache搭配使用,稱為DoubleBlockCache //淘汰了
BucketCache //推薦用的 堆外內存機制 cdh用的這個
CombinedBlockCache:HBase將BucketCache和LRUBlockCache搭配使用,稱為CombinedBlockCache。
總結:
所以經過上面的分析之后,最后剩下LRU君(LRUBlockCache)和CBC君(CombinedBlockCache)。
我們具體分析:
結論
看完了所有比較重要的指標對比數據,我們可以得出以下兩點:
參考鏈接:
HBase BlockCache系列 – 走進BlockCache http://hbasefly.com/2016/04/08/hbase-blockcache-1/
HBase BlockCache系列 - 探求BlockCache實現機制 http://hbasefly.com/2016/04/26/hbase-blockcache-2/
HBase BlockCache系列 - 性能對比測試報告 http://hbasefly.com/2016/05/06/hbase-blockcache-3/
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。