`
lc_koven
  • 浏览: 350250 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

hbase中缓存的优先级

阅读更多
    今天同事问到hbase中in-memory属性的作用,以前没有注意过,今天仔细看了下代码:
      // Instantiate priority buckets
      BlockBucket bucketSingle = new BlockBucket(bytesToFree, blockSize,
          singleSize());
      BlockBucket bucketMulti = new BlockBucket(bytesToFree, blockSize,
          multiSize());
      BlockBucket bucketMemory = new BlockBucket(bytesToFree, blockSize,
          memorySize());

      // Scan entire map putting into appropriate buckets
      for(CachedBlock cachedBlock : map.values()) {
        switch(cachedBlock.getPriority()) {
          case SINGLE: {
            bucketSingle.add(cachedBlock);
            break;
          }
          case MULTI: {
            bucketMulti.add(cachedBlock);
            break;
          }
          case MEMORY: {
            bucketMemory.add(cachedBlock);
            break;
          }
        }
      }

      PriorityQueue<BlockBucket> bucketQueue =
        new PriorityQueue<BlockBucket>(3);

      bucketQueue.add(bucketSingle);
      bucketQueue.add(bucketMulti);
      bucketQueue.add(bucketMemory);

      int remainingBuckets = 3;
      long bytesFreed = 0;

      BlockBucket bucket;
      while((bucket = bucketQueue.poll()) != null) {
        long overflow = bucket.overflow();
        if(overflow > 0) {
          long bucketBytesToFree = Math.min(overflow,
            (bytesToFree - bytesFreed) / remainingBuckets);
          bytesFreed += bucket.free(bucketBytesToFree);
        }
        remainingBuckets--;
      }

    hbase内部的blockcache分三个队列:single、multi以及memory,分别占用25%,50%,25%的大小。这涉及到family属性中的in-memory选项,默认是false。
    设为false的话,第一次访问到该数据时,会将它写入single队列,否则写入memory队列。当再次访问该数据并且在single中读到了该数据时,single会升级为multi
    这三个队列其实是在共用blockcache的资源,区别是在LRU淘汰数据时,single会优先淘汰,其次为multi,最后为memory。

    所以结论有两点:
    1 同一个family不会占用全部的blockcache资源
    2 当某些family特别重要时,可以将它的in-memory设为true,单独使用一个缓存队列,保证cache的优先使用
分享到:
评论
4 楼 chenchao051 2012-08-08  
chenchao051 写道
请教个有个问题:
  public CachedBlock(BlockCacheKey cacheKey, Cacheable buf, long accessTime,
      boolean inMemory) {
    this.cacheKey = cacheKey;
    this.buf = buf;
    this.accessTime = accessTime;
    this.size = ClassSize.align(cacheKey.heapSize())
        + ClassSize.align(buf.heapSize()) + PER_BLOCK_OVERHEAD;
    if(inMemory) {
      this.priority = BlockPriority.MEMORY;
    } else {
      this.priority = BlockPriority.SINGLE;
    }
  }

按照这个说法,假如HBase中没有任何cf的in-memory是true,那么blockcache中25%的in-memory是否就这么被浪费了,我的实际使用过程中也差不多这个情况,一直是75%的占用。

今天再仔细看了下源代码,理解了。
3 楼 chenchao051 2012-08-06  
请教个有个问题:
  public CachedBlock(BlockCacheKey cacheKey, Cacheable buf, long accessTime,
      boolean inMemory) {
    this.cacheKey = cacheKey;
    this.buf = buf;
    this.accessTime = accessTime;
    this.size = ClassSize.align(cacheKey.heapSize())
        + ClassSize.align(buf.heapSize()) + PER_BLOCK_OVERHEAD;
    if(inMemory) {
      this.priority = BlockPriority.MEMORY;
    } else {
      this.priority = BlockPriority.SINGLE;
    }
  }

按照这个说法,假如HBase中没有任何cf的in-memory是true,那么blockcache中25%的in-memory是否就这么被浪费了,我的实际使用过程中也差不多这个情况,一直是75%的占用。
2 楼 lc_koven 2011-11-15  
xuqianghit 写道
“区别是在LRU淘汰数据时,single会优先淘汰,其次为multi,最后为memory。 ”?这个淘汰时应该是按照BlockBucket的compareTo方法来决定bucketQueue.poll()的结构吧,而BlockBucket的compareTo方法中是按照return this.overflow() > that.overflow() ? 1 : -1;比较的,那这样的话,就不是按照“single会优先淘汰,其次为multi,最后为memory”这种顺序了吧?

不知道是不是我的理解错误,谢谢。

恩,前面说的是一个近似的理解。实际上要根据overflow的结果来看。不过实际应用中single确实会比multi先淘汰,这是因为single进入更为频繁。
1 楼 xuqianghit 2011-11-14  
“区别是在LRU淘汰数据时,single会优先淘汰,其次为multi,最后为memory。 ”?这个淘汰时应该是按照BlockBucket的compareTo方法来决定bucketQueue.poll()的结构吧,而BlockBucket的compareTo方法中是按照return this.overflow() > that.overflow() ? 1 : -1;比较的,那这样的话,就不是按照“single会优先淘汰,其次为multi,最后为memory”这种顺序了吧?

不知道是不是我的理解错误,谢谢。

相关推荐

Global site tag (gtag.js) - Google Analytics