Block Cache
HBase提供了两种不同的BlockCache实现,用于缓存从HDFS读出的数据。这两种分别为:
-
默认的,存在于堆内存的(on-heap)LruBlockCache
-
存在堆外内存的(off-heap)BucketCache
下面我们会讨论每种方法的优点和缺点、如何对两种方式做选择,以及这两种类型的相关配置。
Cache Choices
LruBlockCache是最初始的实现,并且全部存在Java堆内存中。BucketCache是另一个选择,主要用于将block cache的数据存在off-heap(堆外内存),不过BlockCache也可以作为一种文件备份式的缓存。
当开启了BucketCache后,便启用了两级缓存的系统。以前我们会用“L1”和“L2”来描述这两个等级,但是现在这个术语已经在hbase-2.0.0后被弃用了。现在“L1” cache 直接指的是LruBlockCache,“L2”指的是一个off-heap的BucketCache。(hbase-2.0.02之后)当BucketCache启用后,所有数据块(DATA block)会被存在BucketCache 层,而meta 数据块(INDEX 以及BLOOM块)被存在on-heap的LruBlockCache中。管理这两层缓存,以及指示数据块如何在它们之间移动的策略,由CombinedBlockCache完成。
Cache的常规配置
除了缓存它自己的实现以外,我们也可以设置一些常规的配置选项,用于控制cache的行为。具体可以参考CacheConfig的文档:
https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/io/hfile/CacheConfig.html
在设置或修改了任何属性后,需要重启HBase集群以让配置文件生效。若是遇到异常,可以进一步查看HBase中的报错。
LruBlockCache的设计
LruBlockCache是一个LRU缓存,包括三种优先级,以适应于于:scan-resistance 以及 in-memory ColumnFamilies场景。三种优先级分别为:
-
Single Access 优先级:当一个数据块第一次从HDFS读取时,它会具有这种优先级,并且在缓存空间需要被回收(置换)时,它属于优先被考虑范围内。它的优点在于:一般被扫描(scanned)读取的数据块,相较于之后会被用到的数据块,更应该被优先清除
-
Multi Access优先级:如果一个数据块,属于Single Access优先级,但是之后被再次访问,则它会升级为Multi Access优先级。在缓存里的内容需要被清除(置换)时,这部分内容属于次要被考虑的范围
-
In-memory Access优先级:如果数据块族被配置为“in-memory”,则会具有这种优先级,并且与它被访问的次数无关。HBase Catalog便是被配置的这个优先级。在缓存里的内容需要被置换时,这部分内容属于最后被考虑的范围。若是需要将一个列族标注为此优先级:
-
在Java中可以调用: HColumnDescriptor.setInMemory(true);
-
在hbase shell 中创建或修改一个表时,可以使用 IN_MEMORY => true,例如:create ‘t’, {NANME => ‘f’, IN_MEMORY => ‘true’}
-
若是想了解更具体的信息,可以参考LruBlockCache 源码
LruBlockCache 的使用
一般来说,BlockCache在所有用户表中默认是开启的,也就是说,任何的读操作均会加载LRU Cache。这个方案可能适用于大部分场景,但是,如果需要达到更优的performance,仍需要