Hbase 的BlockCache

HBase在实现中提供了两种缓存结构:MemStore和BlockCache,memstore主要用于写缓存,而blockcache用于读缓存。其中MemStore称为写缓存,HBase执行写操作首先会将数据写入MemStore,并顺序写入HLog,memstore中的数据达到系统设置的水位值后,会触发flush将memstore中的数据刷写到磁盘。这种设计可以极大地提升HBase的写性能。不仅如此,MemStore对于读性能也至关重要,假如没有MemStore,读取刚写入的数据就需要从文件中通过IO查找,这种代价显然是昂贵的!

BlockCache称为读缓存。客户的读请求会先到memstore中查数据,若查不到就到blockcache中查,再查不到就会从磁盘上读,并把读入的数据同时放入blockcahce。我们知道缓存有三种不同的更新策略,分别是FIFO(先入先出 - First Input First Output)、LRU(最近最少使用 - Least recently used )和LFU(最近最不常使用 - Least Frequently Used),hbase的block使用的是LRU策略,当BlockCache的大小达到上限后,会触发缓存淘汰机制,将最老的一批数据淘汰掉。

一个RegionServer上有一个BlockCache和N个Memstore。

BlockCache在HBase中所处的位置如下图中所示:

BlockCache的实现是基于On-heap ConcurrentHashMap。map的key是BlockCacheKey类型的对象,包括了offset、hfileName等成员变量,map的value是LruCachedBlock类型的对象,表示缓存的实体,该对象中定义了成员变量accesstime,用于LRU淘汰时的比较依据。BlockCache的大小是固定的,由参数hfile.block.cache.size决定,默认是RegionServer的堆内存的40%。

在介绍BlockCache之前,简单地回顾一下HBase中Block的概念,详细介绍戳这里。 Block是HBase中最小的数据存储单元,默认为64K,在建表语句中可以通过参数BlockSize指定。HBase中Block分为四种类型:Data Block,Index Block,Bloom Block和Meta Block。其中Data Block用于存储实际数据,通常情况下每个Data Block可以存放多条KeyValue数据对;Index Block和Bloom Block都用于优化随机读的查找路径,其中Index Block通过存储索引数据加快数据查找,而Bloom Block通过一定算法可以过滤掉部分一定不存在待查KeyValue的数据文件,减少不必要的IO操作;Meta Block主要存储整个HFile的元数据。

BlockCache是Region Server级别的,一个Region Server只有一个Block Cache,在Region Server启动的时候完成Block Cache的初始化工作。到目前为止,HBase先后实现了3种Block Cache方案,LRUBlockCache是最初的实现方案,也是默认的实现方案;HBase 0.92版本实现了第二种方案SlabCache,见HBASE-4027;HBase 0.96之后官方提供了另一种可选方案BucketCache,见HBASE-7404

这三种方案的不同之处在于对内存的管理模式,其中LRUBlockCache是将所有数据都放入JVM Heap中,交给JVM进行管理。而后两者采用了不同机制将部分数据存储在堆外,交给HBase自己管理。这种演变过程是因为LRUBlockCache方案中JVM垃圾回收机制经常会导致程序长时间暂停,而采用堆外内存对数据进行管理可以有效避免这种情况发生。


关于LruBlockCache BucketCache 参见播客
LruBlockCache 默认的,存在于堆内存的(on-heap)
BucketCache 存在堆外内存的(off-heap)
https://www.cnblogs.com/zackstang/p/10061379.html
https://www.cnblogs.com/panfeng412/archive/2012/09/24/hbase-block-cache-mechanism.html
 

发布了131 篇原创文章 · 获赞 79 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/qq_31780525/article/details/100581239
今日推荐