分享

最近发现hbase 老有节点掉线,查看了日志,掉线前出现大量的信息

hyj 发表于 2014-4-13 11:03:40 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 1 8809
请教大家个hadoop 的问题,最近发现hbase 老有节点掉线,查看了日志,掉线前出现大量的
2014-03-10 12:30:10,452 DEBUG org.apache.hadoop.hbase.io.hfile.LruBlockCache: Block cache LRU eviction started; Attempting to free 24.74 MB of total=209.89 MB


已有(1)人评论

跳转到指定楼层
pig2 发表于 2014-4-13 11:15:09
由于BlockCache采用的是LRU策略,因此BlockCache达到上限(heapsize * hfile.block.cache.size * 0.85)后,会启动淘汰机制,淘汰掉最老的一批数据。
hbase在操作Block Cache的LRU淘汰过程中:

看如下函数:

  1. /**
  2.    * Eviction method.
  3.    */
  4.   void evict() {
  5.      
  6.     // Ensure only one eviction at a time
  7.     if(!evictionLock.tryLock()) return;
  8.      
  9.     try {
  10.       evictionInProgress = true;
  11.       long currentSize = this.size.get();
  12.       long bytesToFree = currentSize - minSize();
  13.      
  14.       if (LOG.isDebugEnabled()) {
  15.         LOG.debug("Block cache LRU eviction started; Attempting to free " +
  16.           StringUtils.byteDesc(bytesToFree) + " of total=" +
  17.           StringUtils.byteDesc(currentSize));
  18.       }
  19.      
  20.       if(bytesToFree <= 0) return;
  21.      
  22.       // Instantiate priority buckets
  23.       BlockBucket bucketSingle = new BlockBucket(bytesToFree, blockSize,
  24.           singleSize());
  25.       BlockBucket bucketMulti = new BlockBucket(bytesToFree, blockSize,
  26.           multiSize());
  27.       BlockBucket bucketMemory = new BlockBucket(bytesToFree, blockSize,
  28.           memorySize());
  29.      
  30.       // Scan entire map putting into appropriate buckets
  31.       for(CachedBlock cachedBlock : map.values()) {
  32.         switch(cachedBlock.getPriority()) {
  33.           case SINGLE: {
  34.             bucketSingle.add(cachedBlock);
  35.             break;
  36.           }
  37.           case MULTI: {
  38.             bucketMulti.add(cachedBlock);
  39.             break;
  40.           }
  41.           case MEMORY: {
  42.             bucketMemory.add(cachedBlock);
  43.             break;
  44.           }
  45.         }
  46.       }
  47.      
  48.       PriorityQueue<BlockBucket> bucketQueue =
  49.         new PriorityQueue<BlockBucket>(3);
  50.      
  51.       bucketQueue.add(bucketSingle);
  52.       bucketQueue.add(bucketMulti);
  53.       bucketQueue.add(bucketMemory);
  54.      
  55.       int remainingBuckets = 3;
  56.       long bytesFreed = 0;
  57.      
  58.       BlockBucket bucket;
  59.       while((bucket = bucketQueue.poll()) != null) {
  60.         long overflow = bucket.overflow();
  61.         if(overflow > 0) {
  62.           long bucketBytesToFree = Math.min(overflow,
  63.             (bytesToFree - bytesFreed) / remainingBuckets);
  64.           bytesFreed += bucket.free(bucketBytesToFree);
  65.         }
  66.         remainingBuckets--;
  67.       }
  68.      
  69.       if (LOG.isDebugEnabled()) {
  70.         long single = bucketSingle.totalSize();
  71.         long multi = bucketMulti.totalSize();
  72.         long memory = bucketMemory.totalSize();
  73.         LOG.debug("Block cache LRU eviction completed; " +
  74.           "freed=" + StringUtils.byteDesc(bytesFreed) + ", " +
  75.           "total=" + StringUtils.byteDesc(this.size.get()) + ", " +
  76.           "single=" + StringUtils.byteDesc(single) + ", " +
  77.           "multi=" + StringUtils.byteDesc(multi) + ", " +
  78.           "memory=" + StringUtils.byteDesc(memory));
  79.       }
  80.     } finally {
  81.       stats.evict();
  82.       evictionInProgress = false;
  83.       evictionLock.unlock();
  84.     }
  85.   }
复制代码
1)首先获取锁,保证同一时刻只有一个淘汰线程运行;

2)计算得到当前Block Cache总大小currentSize及需要被淘汰释放掉的大小bytesToFree,如果bytesToFree小于等于0则不进行后续操作;

3) 初始化创建三个BlockBucket队列,分别用于存放Single、Multi和InMemory类Block Cache,其中每个BlockBucket维护了一个CachedBlockQueue,按LRU淘汰算法维护该BlockBucket中的所有CachedBlock对象;

4) 遍历记录所有Block Cache的全局ConcurrentHashMap,加入到相应的BlockBucket队列中;

5) 将以上三个BlockBucket队列加入到一个优先级队列中,按照各个BlockBucket超出bucketSize的大小顺序排序(见BlockBucket的compareTo方法);

6) 遍历优先级队列,对于每个BlockBucket,通过Math.min(overflow, (bytesToFree - bytesFreed) / remainingBuckets)计算出需要释放的空间大小,这样做可以保证尽可能平均地从三个BlockBucket中释放指定的空间;具体实现过程详见BlockBucket的free方法,从其CachedBlockQueue中取出即将被淘汰掉的CachedBlock对象:


总结:
明白了上面内容,很明显是我们在启用淘汰机制的时候,发生了掉线,可以从原理上来解决,根据个人推测,这个应该可以自动修复。



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条