HBase BucketAllocatorException 异常剖析

HBase BucketAllocatorException 异常剖析近日,观察到HBase集群出现如下WARN日志: 2020 04 18 16:17:03,081 WARN [regionserver/xxx BucketCacheWriter 1] bucket.

HBase BucketAllocatorException 异常剖析

近日,观察到HBase集群出现如下WARN日志:

2020-04-18 16:17:03,081 WARN [regionserver/xxx-BucketCacheWriter-1] bucket.BucketCache:Failed allocation for 604acc82edd349ca906939af14464bcb_175674734;
org.apache.hadoop.hbase.io.hfile.bucket.BucketAllocatorException: Allocation too big size=1114202; adjust BucketCache sizes hbase.bucketcache.bucket.sizes to accomodate if size seems reasonable and you want it cached.

大概意思是说:由于block块太大(size=1114202)导致BucketAllocator无法为其分配空间,如果想要被缓存并且觉得这样做合理,可以调整参数hbase.bucketcache.bucket.sizes。

默认情况下,HBase BucketCache 能够缓存block的最大值为512KB,即hbase.bucketcache.bucket.sizes=5120,9216,17408,33792,41984,50176,58368,66560,99328,132096,197632,263168,394240,525312,默认14种size标签。如果想要缓存更大的block块,我们可以调整参数为 hbase.bucketcache.bucket.sizes=5120,9216,17408,33792,41984,50176,58368,66560,99328,132096,197632,263168,394240,525312,1049600,2098176,此时最大容许2MB的block。

下面我们简单看一下对应源代码,涉及相关类为:
/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketAllocator.java
BucketAllocator主要实现对bucket的组织管理,为block分配内存空间。

/**
   * Allocate a block with specified size. Return the offset
   * @param blockSize size of block
   * @throws BucketAllocatorException
   * @throws CacheFullException
   * @return the offset in the IOEngine
   */
  public synchronized long allocateBlock(int blockSize) throws CacheFullException,
      BucketAllocatorException {
    assert blockSize > 0;
    BucketSizeInfo bsi = roundUpToBucketSizeInfo(blockSize);
    if (bsi == null) {
      throw new BucketAllocatorException("Allocation too big size=" + blockSize +
        "; adjust BucketCache sizes " + BlockCacheFactory.BUCKET_CACHE_BUCKETS_KEY +
        " to accomodate if size seems reasonable and you want it cached.");
    }
    long offset = bsi.allocateBlock();

    // Ask caller to free up space and try again!
    if (offset < 0)
      throw new CacheFullException(blockSize, bsi.sizeIndex());
    usedSize += bucketSizes[bsi.sizeIndex()];
    return offset;
  }

代码100分

在调用roundUpToBucketSizeInfo()方法后,返回结果如果为null则抛出BucketAllocatorException异常。看一下roundUpToBucketSizeInfo()方法:

代码100分/**
 * Round up the given block size to bucket size, and get the corresponding
 * BucketSizeInfo
*/
public BucketSizeInfo roundUpToBucketSizeInfo(int blockSize) {
	for (int i = 0; i < bucketSizes.length; ++i)
	  if (blockSize <= bucketSizes[i])
		return bucketSizeInfos[i];
	return null;
}

该方法将传入的blockSize与数组bucketSizes从索引0开始取值进行比较,一旦小于bucketSize[i],则为该block分配bucketSizeInfos[i]大小的空间存放该block。

我们看一下数组bucketSizes的初始化过程:

private static final int DEFAULT_BUCKET_SIZES[] = { 4 * 1024 + 1024, 8 * 1024 + 1024,
  16 * 1024 + 1024, 32 * 1024 + 1024, 40 * 1024 + 1024, 48 * 1024 + 1024,
  56 * 1024 + 1024, 64 * 1024 + 1024, 96 * 1024 + 1024, 128 * 1024 + 1024,
  192 * 1024 + 1024, 256 * 1024 + 1024, 384 * 1024 + 1024,
  512 * 1024 + 1024 };

private final int[] bucketSizes;
BucketAllocator(long availableSpace, int[] bucketSizes)
  throws BucketAllocatorException {
  this.bucketSizes = bucketSizes == null ? DEFAULT_BUCKET_SIZES : bucketSizes;
  Arrays.sort(this.bucketSizes);
  ...
}

可以看到,如果bucketSizes == null默认取数组DEFAULT_BUCKET_SIZES的值,并对该数组进行排序。这一步的排序为上一步的循环比较奠定了基础。

而数组DEFAULT_BUCKET_SIZES的值,也就是参数hbase.bucketcache.bucket.sizes的默认值。

扫描二维码关注博主公众号

转载请注明出处!欢迎关注本人微信公众号【HBase工作笔记】

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/8886.html

(0)
上一篇 2023-02-20
下一篇 2023-02-20

相关推荐

  • Python中e等于多少?

    Python中e等于多少?e是一个数学常数,约等于2.71828,是以自然常数为底的指数函数的底数,也是某些数学公式的重要参数。在Python中,e可以通过math库来获取:

    2024-02-21
    46
  • mysql中文翻译_MySQL comment

    mysql中文翻译_MySQL commentMySQL version: 5.7 点击进入官方文档 14.6.6 Redo Log redo log是一种基于磁盘的数据结构,用于在崩溃恢复期间纠正由不完整事务写入的数据。在正常操作期间,red…

    2023-02-28
    97
  • t+0的技巧_T教石峰

    t+0的技巧_T教石峰摘要:T+0查询是指实时数据查询,数据查询统计时将涉及到最新产生的数据。 本文分享自华为云社区《大数据解决方案:解决T+0问题》,作者: 小虚竹 。 T+0问题 T+0查询是指实时数据查询,数据查询统

    2023-06-12
    106
  • MySQL学习笔记(9):索引「建议收藏」

    MySQL学习笔记(9):索引「建议收藏」本文更新于2019-07-27,使用MySQL 5.7,操作系统为Deepin 15.4。 在创建一个n列的复合索引时,实际是创建了n个索引。可利用索引中最左边的列集来匹配行,这样的列集称为最左前缀。

    2023-03-17
    107
  • mysql亿级数据数据库优化方案测试-银行交易流水记录的查询[亲测有效]

    mysql亿级数据数据库优化方案测试-银行交易流水记录的查询[亲测有效]对MySQL的性能和亿级数据的处理方法思考,以及分库分表到底该如何做,在什么场景比较合适? 比如银行交易流水记录的查询 限盐少许,上实际实验过程,以下是在实验的过程中做一些操作,以及踩过的一些坑,我…

    2023-03-29
    109
  • SQL 如何插入、删除和更新数据「终于解决」

    SQL 如何插入、删除和更新数据「终于解决」本文将会给大家介绍 DBMS 中用来更新表中数据的方法。SQL 数据的更新处理大体可以分为插入(INSERT)、删除(DELETE)和更新(UPDATE)三类。本文将会对这三类更新方法进行详细介绍。

    2023-05-21
    87
  • oracle创建用户并赋权_oracle 删除用户

    oracle创建用户并赋权_oracle 删除用户首发微信公众号:SQL数据库运维 原文链接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247485212&idx=1

    2023-06-02
    97
  • Python MongoDB GroupBy 实现

    Python MongoDB GroupBy 实现MongoDB是一个非关系型数据库管理系统,它以BSON (Binary JSON) 数据格式,存储数据。使用MongoDB进行数据查询时,常常需要对数据进行聚合操作,这就需要用到GroupBy操作。本文介绍如何使用Python实现MongoDB的GroupBy操作。

    2024-05-02
    15

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注