BlockCache

2021-08-30  本文已影响0人  ZYvette

提升读取性能方法:热点数据存储到内存中,以避免昂贵的IO开销。

HBase也实现了一种读缓存结构——BlockCache。
客户端读取某个Block,首先会检查该Block是否存在于Block Cache,如果存在就直接加载出来,如果不存在则去HFile文件中加载,加载出来之后放到Block Cache中,后续同一请求或者邻近数据查找请求可以直接从内存中获取,以避免昂贵的IO操作。

BlockCache主要用来缓存Block。需要关注的是,Block是HBase中最小的数据读取单元,即数据从HFile中读取都是以Block为最小单元执行的。

BlockCache是RegionServer级别的,一个RegionServer只有一个BlockCache,在RegionServer启动时完成BlockCache的初始化工作。

BlockCache 三种:
LRUBlockCache
SlabCache
BucketCache

不同之处主要在于内存管理模式,其中LRUBlockCache是将所有数据都放入JVM Heap中,交给JVM进行管理。
而后两种方案采用的机制允许将部分数据存储在堆外。
这种演变本质上是因为LRUBlockCache方案中JVM垃圾回收机制经常导致程序长时间暂停,而采用堆外内存对数据进行管理可以有效缓解系统长时间GC。

LRUBlockCache

ConcurrentHashMap管理BlockKey到Block的映射关系,缓存Block只需要将BlockKey和对应的Block放入该HashMap中,查询缓存就根据BlockKey从HashMap中获取即可。

在一次随机读中,一个Block从HDFS中加载出来之后首先放入single-access区,后续如果有多次请求访问到这个Block,就会将这个Block移到multi-access区。而in-memory区表示数据可以常驻内存,一般用来存放访问频繁、量小的数据,比如元数据,用户可以在建表的时候设置列簇属性IN_MEMORY=true,设置之后该列簇的Block在从磁盘中加载出来之后会直接放入in-memory区。

SlabCache

SlabCache方案提出使用Java NIO DirectByteBuffer技术实现堆外内存存储,不再由JVM管理数据内存。
a.Java NIO DirectByteBuffer技术实现堆外内存存储,不再由JVM管理数据内存
b. BlockCache大小的80%和20%,每个缓存区分别存储固定大小的Block,其中前者主要存储小于等于64K的Block,后者存储小于等于128K的Block,如果一个Block太大就会导致两个区都无法缓存。
c. DoubleBlockCache方案有很多弊端。比如,SlabCache中固定大小内存设置会导致实际内存使用率比较低,而且使用LRUBlockCache缓存Block依然会因为JVM GC产生大量内存碎片。

BucketCache

BucketCache工作模式

heap: 数据存在JVM,会发生GC,但是读取方便
offheap: 因为内存属于操作系统,所以大大降低了因为内存碎片导致Full GC的风险。但是读取数据是,需要从offheap复制到JVM heap,读取耗时。
file: 一般使用ssd,加个昂贵,但是因存储空间大,极大提高了缓存命中率。

上一篇下一篇

猜你喜欢

热点阅读