HBase_blockcache

本文大范围的借鉴了博主的文章,只是为了便于自己的记忆和理解,并没有做其他用途

BlockCache

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

HBase默认的BlockCache实现方案。Block数据块都存储在 JVM heap内,由JVM进行垃圾回收管理。它将内存从逻辑上分为了三块:single-access区、mutil-access区、in-memory区,分别占到整个BlockCache大小的25%、50%、25%。一次随机读中,一个Block块从HDFS中加载出来之后首先放入signle区,后续如果有多次请求访问到这块数据的话,就会将这块数据移到mutil-access区。而in-memory区表示数据可以常驻内存,一般用来存放访问频繁、数据量小的数据,比如元数据,用户也可以在建表的时候通过设置列族属性IN-MEMORY= true将此列族放入in-memory区。很显然,这种设计策略类似于JVM中young区、old区以及perm区。无论哪个区,系统都会采用严格的Least-Recently-Used算法,当BlockCache总量达到一定阈值之后就会启动淘汰机制,最少使用的Block会被置换出来,为新加载的Block预留空间。

SlabCache

SlabCache方案使用Java NIO DirectByteBuffer技术实现了堆外内存存储,不再由JVM管理数据内存。默认情况下,系统在初始化的时候会分配两个缓存区,分别占整个BlockCache大小的80%和20%.和LRUBlockCache相同,SlabCache也使用Least-Recently-Used算法对过期Block进行淘汰。和LRUBlockCache不同的是,SlabCache淘汰Block的时候只需要将对应的bufferbyte标记为空闲,后续cache对其上的内存直接进行覆盖即可。

BucketCache

BucketCache通过配置可以工作在三种模式下:heap,offheap和file。无论工作在那种模式下,BucketCache都会申请许多带有固定大小标签的Bucket,一种Bucket存储一种指定BlockSize的数据块,BucketCache会在初始化的时候申请14个不同大小的Bucket,而且即使在某一种Bucket空间不足的情况下,系统也会从其他Bucket空间借用内存使用,不会出现内存使用率低的情况。heap模式表示这些Bucket是从JVM Heap中申请,offheap模式使用DirectByteBuffer技术实现堆外内存存储管理,而file模式使用类似SSD的高速缓存文件存储数据块。

实际实现中,HBase将BucketCache和LRUBlockCache搭配使用,称为CombinedBlockCache。系统在LRUBlockCache中主要存储Index Block和Bloom Block,而将Data Block存储在BucketCache中。

BucketCache工作模式

BucketCache默认有三种工作模式:heap、offheap和file;这三种工作模式在内存逻辑组织形式以及缓存流程上都是相同的,不同的是三者对应的最终存储介质有所不同.其中heap模式和offheap模式都使用内存作为最终存储介质,file模式和前面两者不同,它使用Fussion-IO或者SSD等作为存储介质,相比昂贵的内存,这样可以提供更大的存储容量,因此可以极大地提升缓存命中率。

内存分配查询也都使用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再读取,显得后者更费时。

Share