深入理解hbase(三)Hbase中的BucketCache

深入了解Hbase中的BucketCache

(1)BucketCache组织结构

在这里插入图片描述

上图为BucketCache的内存组织形式,图中上半部分是逻辑组织结构,下半部分是对应的物理组织结构。HBase启动之后会在内存中申请大量的Bucket,每个 Bucket的大小默认为2MB。

每个 Bucket 会有一个baseoffset变量和一个size标签,其中 baseoffset变量表示这个Bucket在实际物理空间中的起始地址,因此Block 的物理地址就可以通过baseoffset和该Block在 Bucket的偏移量唯一确定;size标签表示这个Bucket可以存放的Block大小,比如图中左侧Bucket的size标签为65KB,表示可以存放64KB的Block,右侧Bucket的 size标签为129KB,表示可以存放128KB的 Block。

bucket的组织管理

HBase中使用BucketAllocator类实现对 Bucket的组织管理。
1)HBase会根据每个Bucket的 size标签对Bucket进行分类,相同size标签的Bucket由同一个 BucketSizeInfo管理,如图所示,左侧存放64KB Block 的 Bucket由 65KBBucketSizeInfo管理,右侧存放128KB Block 的Bucket由 129KB BucketSizeInfo管理。可见,BucketSize大小总会比 Block本身大1KB,这是因为Block本身并不是严格固定大小的,总会大那么一点,比如64K的 Block总是会比64K大一些。

  1. HBasc在启动的时候就决定了size标签的分类,默认标签有(4+1)K,(8+1)K,(16+1)K…(48+1)K,(56+1)K,(64+1)K,(96+1)K…(512+1)K。而且系统会首先从小到大遍历一次所有size标签,为每种size标签分配一个 Bucket,最后所有剩余的Bucket都分配最大的size标签,默认分配(512+1)K

在这里插入图片描述

(2)BucketCache中Block缓存写入、读取流程

  • RAMCache是一个存储blockKey和 Block 对应关系的HashMap。
  • WriteThead是整个Block写入的中心枢纽,主要负责异步地将Block写入到内存空间。
  • BucketAllocator主要实现对Bucket的组织管理,为Block分配内存空间。
  • IOEngine是具体的内存管理模块,将 Block 数据写入对应地址的内存空间。
  • BackingMap也是一个HashMap,用来存储blockKey与对应物理内存偏移量的映射关系,并且根据blockKey定位具体的Block。

图中实线表示Block 写入流程,虚线表示 Block缓存读取流程。
在这里插入图片描述

1、缓存写入流程

1)将Block 写入RAMCache。实际实现中,HBase,设置了多个RAMCache,系统首先会根据blockKey进行hash,根据hash结果将Block分配到对应的RAMCache中。

2 ) WriteThead 从 RAMCache中取出所有的Block。和RAMCache相同,HBase 会同时启动多个 WriteThead并发地执行异步写入,每个 WriteThead对应一个RAMCache。

3)每个 WriteThead会遍历RAMCache中所有Block,分别调用bucketAllocator为这些Block分配内存空间。

4 ) BucketAllocator 会选择与Block大小对应的 Bucket进行存放,并且返回对应的物理地址偏移量offset。

5 ) WriteThead将 Block以及分配好的物理地址偏移量传给IOEngine模块,执行具体的内存写入操作。

6)写入成功后,将blockKey与对应物理内存偏移量的映射关系写入BackingMap中,方便后续查找时根据blockKey直接定位。

2、缓存读取流程

1)首先从RAMCache中查找。对于还没有来得及写入Bucket的缓存Block,一定存储在RAMCache 中。

2)如果在RAMCache中没有找到,再根据blockKey在 BackingMap中找到对应的物理偏移地址量offset。

3)根据物理偏移地址offset直接从内存中查找对应的 Block数据。

(3)BucketCache的工作模式

​ BucketCache默认有三种工作模式: heap、offheap和 file。这三种工作模式在内存逻辑组织形式以及缓存流程上都是相同的;但是三者对应的最终存储介质有所不同,即上述所讲的IOEngine有所不同。

​ heap模式和 offheap模式都使用内存作为最终存储介质,内存分配查询也都使用JavaNIO ByteBuffer 技术。二者不同的是,heap模式分配内存会调用ByteBuffer.allocate方法,从JVM提供的heap区分配; 而 offheap模式会调用ByteBuffer.allocateDirect方法,直接从操作系统分配。

这两种内存分配模式会对HBase实际工作性能产生一定的影响。影响最大的无疑是GC,相比 heap模式,offheap模式因为内存属于操作系统,所以大大降低了因为内存碎片导致Full GC的风险。除此之外,在内存分配以及读取方面,两者性能也有不同,比如,内存分配时,相比 offheap直接从操作系统分配内存,heap模式需要首先从操作系统分配内存再拷贝到JVM heap,因此更耗时;但是反过来,读取缓存时heap模式可以从JVM heap中直接读取,而 offheap模式则需要首先从操作系统拷贝到JVM heap再读取,因此更费时。

​ file模式和前面两者不同,它使用Fussion-IO或者SSD等作为存储介质,相比昂贵的内存,这样可以提供更大的存储容量,因此可以极大地提升缓存命中率。

(4)BucketCache的配置

heap模式

<!--bucketcache存储介质,可取值包括heap,offheap和file三种,分别表示堆内内存,堆外内存和文件-->
<property>
	<name>hbase.bucketcache.ioengine</name>
    <value>heap</value>
</property>

<!--bucketcache 大小,可取值有两种,一种是大于0小于1的浮点型数值,表示占总内存的百分比。另一种是大于1的值,表示所占内存大小,单位为M-->
<property>
	<name>hbase.bucketcache.size</name>
    <value>0.4</value>
</property>

ffheap模式

<property>
	<name>hbase.bucketcache.ioengine</name>
    <value>offheap</value>
</property>

<property>
	<name>hbase.bucketcache.size</name>
    <value>0.4</value>
</property>

file模式

<property>
	<name>hbase.bucketcache.ioengine</name>
    <value>file</value>
</property>

<!--bucketcache缓存空间大小,单位为MB-->
<property>
	<name>hbase.bucketcache.size</name>
    <value>10 * 1024</value>
</property>

<property>
	<name>hbase.bucketcache.persistent.path</name>
    <value>file:/cache_path</value>
</property>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值