13 hbase源码系列(十三)缓存机制MemStore与Block Cache

本文详细介绍了HBase的缓存机制,包括MemStore的有序集合和MemStoreLAB,以及CacheConfig中的BlockCache和BucketCache。MemStore通过MemStoreLAB减少内存碎片,使用两个有序集合(kvset和snapshot)保持数据顺序。BlockCache分为LruBlockCache和BucketCache,后者可作为二级缓存使用,如SSD。文章强调了缓存参数设置对性能的影响,并讨论了HBase的内存管理策略。
摘要由CSDN通过智能技术生成

这一章讲hbase的缓存机制,这里面涉及的内容也是比较多,呵呵,我理解中的缓存是保存在内存中的特定的便于检索的数据结构就是缓存。

之前在讲put的时候,put是被添加到Store里面,这个Store是个接口,实现是在HStore里面,MemStore其实是它底下的小子。

那它和Region Server、Region是什么关系?

Region Server下面有若干个Region,每个Region下面有若干的列族,每个列族对应着一个HStore。

HStore里面有三个很重要的类,在这章的内容都会提到。

protected final MemStore memstore;
private final CacheConfig cacheConf;
final StoreEngine<?, ?, ?, ?> storeEngine;

MemStore是存储着两个有序的kv集合,kv进来先写到里面,超过阀值之后就会写入硬盘。

CacheConf是针对HFileBlock的缓存,专门用来缓存快,默认是在读的时候缓存块,也可以修改列族的参数,让它在写的时候也缓存,这个在数据模型定义的时候提到过。

StoreEngine是StoreFile的管理器,它管理着这个列族对应的所有StoreFiles。

1. MemStore

memstore比较有意思,我们先看它的add方法,这个是入口。

long add(final KeyValue kv) {
    this.lock.readLock().lock();
    try {
      KeyValue toAdd = maybeCloneWithAllocator(kv);
      return internalAdd(toAdd);
    } finally {
      this.lock.readLock().unlock();
    }
}

先把kv放到maybeCloneWithAllocator里面复制出来一个新的kv,然后再走internalAdd的方法,为啥要这么搞呢?

1.1 MemStoreLAB

先看maybeCloneWithAllocator,我们慢慢看,没关系。

private KeyValue maybeCloneWithAllocator(KeyValue kv) {
    if (allocator == null) {
      return kv;
    }
    int len = kv.getLength();
    //从allocator当中分配出来len长度的非堆空间
    Allocation alloc = allocator.allocateBytes(len);
    if (alloc == null) {
      // 太大了,allocator决定不给它分配return kv;
    }
    //用allocator生成的空间,new一个kv出来assert alloc != null && alloc.getData() != null;
    System.arraycopy(kv.getBuffer(), kv.getOffset(), alloc.getData(), alloc.getOffset(), len);
    KeyValue newKv = new KeyValue(alloc.getData(), alloc.getOffset(), len);
    newKv.setMvccVersion(kv.getMvccVersion());
    return newKv;
 }

allocator是何许人也,它是一个MemStoreLAB,它是干啥的呀,这个让人很纠结呀?

public Allocation allocateBytes(int size) {
    // 如果申请的size比maxAlloc大,就不分了if (size > maxAlloc) {
      return null;
    }

    while (true) {
      Chunk c = getOrMakeChunk();

      // 给它分配个位置,返回数组的起始位置int allocOffset = c.alloc(size);
      if (allocOffset != -1) {
        // 用一个数据结构Allocation来描述这个,它主要包括两个信息,1:数组的引用,2:数据在数组当中的起始位置return new Allocation(c.data, allocOffset);
      }

      // 空间不足了,释放掉它      tryRetireChunk(c);
    }
}

下面看看getOrMakeChunk看看是啥情况,挺疑惑的东西。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值