HBase BlockCache簡介

MemStore 作為 HBase 的寫緩存,保存著數據的最近一次更新,響應的 BlockCache 作為 HBase 的讀緩存,保存著最近被訪問的數據塊。HBase 順序地讀取一個數據塊到內存緩存中,讀取相鄰的數據就可以在內存中讀取而不需要再次從磁盤中讀取,有效減少磁盤IO。使用 Scan API 掃描的時候,建議關閉 BlockCache,Scan 的場景中緩存意義不大。

HBase 讀取數據的時候優(yōu)先查找 MemStore(最新的更新版本),其次會查找 BlockCache。首先了解一下 HBase Block 的概念。

HBase Block

在 HBase 中,存儲文件被劃分成若干個小存儲塊,默認是64k。在 get 或 scan 中一次會完全加載一個 block 到內存中。不同于 HDFS Block,HDFS 層面的塊是用于拆分大文件以提供分布式存儲,HBase Block 塊存在于 HFile 的內部的數據結構,參考 HFile v1 版本:(詳細請看 HFile 詳解)


HBasel HFile v1

在建表語句中可以通過參數BlockSize指定:BLOCKSIZE => '65536'

HBase BlockCache

一個 RegionServer 有一個 BlockCache,在 RegionServer 啟動的時候完成 BlockCache 的初始化工作(參考 RegionServer 啟動源碼)。

HBase 提供了幾種 BlockCache 方案:

LruBlockCache

LruBLockCache 在 JVM 堆中,基于客戶端對數據的訪問頻率,定義了三個不同的優(yōu)先級隊列,設計原理類似于 JVM 的堆分區(qū)策略。

BlockCahce 分級

  • single:block 被第一次訪問,則該 Block 被放在這一優(yōu)先級隊列中。
  • multi:如果一個 Block 被多次訪問,則從 single 移到 multi 中。
  • in memory:in memory 由用戶指定,在內存中常駐,一般不推薦,只用系統(tǒng)表才使用 in memory 優(yōu)先級。

分級的好處在于:
首先,通過 in memory 類型緩存,將重要的數據放到 RegionServer 內存中常駐,例如 Meta 或者 namespace 的元數據信息。
其次,通過區(qū)分 single 和 multi 類型緩存,可以防止由于 scan 操作帶來的 cache 頻繁更替。
默認配置下,對于整個 BlockCache,按照以下百分比分配給 single、multi 和 in memory 使用:0.25、0.5和0.25。無論哪個區(qū),都會采用嚴格的 Least-Recently-Used 算法淘汰機制,最少使用的 Block 會被替換,為新加載的 Block 預留空間。

如果只使用 LruBlockCache,在內存較大時會存在GC的問題導致服務中斷。

SlabCache

為了解決 LRUBlockCache 方案中因為JVM垃圾回收導致的服務中斷,SlabCache 方案使用 Java NIO DirectByteBuffer 技術實現了堆外內存存儲,不再由JVM管理數據內存。

默認情況下,系統(tǒng)在初始化的時候會分配兩個緩存區(qū),分別占整個 BlockCache 大小的80%和20%,其中前者主要存儲小于等于 64K Block,后者存儲小于等于 128K Block,如果一個 Block 超過128K 則兩個區(qū)都不會緩存。SlabCache 也使用 LRU 算法對過期 Block 進行淘汰。和 LRUBlockCache 不同的是,SlabCache 淘汰 Block 的時候只需要將對應的 bufferbyte 標記為空閑,后續(xù) block cache 對其上的內存直接進行覆蓋即可。

由于以下設計上的原因被廢棄:

  • 只能存儲兩種大小標準的 Block,由于不同表和列族的設置,會有多種類型的 block size,這樣會導致內存使用率低,特別是在使用了 DataBlockEncoding 的情況下。
  • 因此,通常會將 SlabCache 和 LRUBlockCache 搭配使用,稱為 DoubleBlockCache。Block 會在 SlabCache 和 LruBlockCache 都緩存一份,讀操作會先查找 LruBlockCache,后查找 SlabCache,當在 SlabCache 中命中時會把 block 重新放回 LruBlockCache。實際應用中比單獨用 LruBlockCache 沒有明顯改善。
  • 堆外內存的性能沒有堆內存高

BucketCache

SlabCache 方案在實際應用中并沒有很大程度改善原有 LruBlockCache 方案的GC弊端,還額外引入了諸如堆外內存使用率低的缺陷。

BucketCache 為了解決了 SlabCache 中存在的問題,首先其支持多種 Cache 方式,通過 hbase.bucketcache.ioengine 配置,有 heap、offheap 和 file 三種:

  • heap 使用jvm中的heap
  • offheap 使用堆外內存
  • file 使用文件的方式,利用SSD硬盤的使用,改進了使用率低的問題。

其次支持了多種不同大小的 bucket,以適應不同大小的 block size??梢酝ㄟ^參數 hbase.bucketcache.bucket.sizes 來配置不同 bucket 的大小。默認是14種,大小分別是4、8、16、32、40、48、56、64、96、128、192、256、384、512KB的block(逗號分隔)。并且,在某一大小類型的 Bucket 空間不足的情況下,系統(tǒng)也會從其他 Bucket 空間借用內存使用,不會出現內存使用率低的情況。

最后,使用堆外內存的性能問題(如拷貝內存)在2.0版本中解決 HBASE-11425

實際實現中,常將 BucketCache 和 LRUBlockCache 搭配使用,稱為 CombinedBlockCache。
在 cache block 的時候會將 MetaBlock(包括 META、INDEX、BLOOM 等非DATA block)放入LruBlockCache,將 DataBlock 存儲在 BucketCache 中。特殊情況是,表中設置了 CACHE_DATA_IN_L1 => 'true' 的 DataBlock 也會存入 LruBlockCache。

ExternalBlockCache

ExternalBlockCache 提供使用外部的緩存服務來進行緩存,如 memcached 和 redis 等。

更具體的緩存細節(jié)參考 HBase BlockCache源碼

HBase 讀路徑

總結,HBase 讀路徑為,首先檢查 MemStore,然后檢查 BlockCache,最后檢索 HFile,并且合并一條數據的信息(read merge)返回給客戶端。


?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • HBase那些事 @(大數據工程學院)[HBase, Hadoop, 優(yōu)化, HadoopChen, hbase]...
    分癡閱讀 4,122評論 3 17
  • [TOC] 摘錄一 hbase.rootdir 這個目錄是region server的共享目錄,用來持久化HBas...
    昨夜今夕閱讀 11,468評論 1 8
  • HBase存儲架構圖 HBase Master 為Region server分配region 負責Region s...
    kimibob閱讀 5,759評論 0 52
  • 簡介 HBase是高可靠性,高性能,面向列,可伸縮的分布式存儲系統(tǒng),利用HBase技術可在廉價PC Serve...
    九世的貓閱讀 2,387評論 1 6
  • 本文首先簡單介紹了HBase,然后重點講述了HBase的高并發(fā)和實時處理數據 、HBase數據模型、HBase物理...
    達微閱讀 2,854評論 1 13

友情鏈接更多精彩內容