[HBase] - 读懂 BucketCache 日志信息

这是 HBase regionserver 打印的一段 bucket cache 统计信息,里面有些指标有点让人摸不着头脑。下面将通过提问的方式,结合实际业务与源码逐一解释各个指标,分析可以尝试优化的点。

2022-05-09 16:26:31,240 INFO [BucketCacheStatsExecutor] bucket.BucketCache: failedBlockAdditions=20681097, totalSize=60.00 GB, freeSize=6.75 GB, usedSize=53.25 GB, cacheSize=52.43 GB, accesses=41703312106, hits=37430928681, IOhitsPerSecond=1577, IOTimePerHit=0.06, hitRatio=89.76%, cachingAccesses=38812699538, cachingHits=37362791550,cachingHitsRatio=96.26%, evictions=14844, evicted=1384179287, evictedPerRun=93248.40625

问题1 : failedBlockAdditions 是什么?
写缓存失败的次数,写缓存流程大概如下,失败出现在第 2 步:

  1. 写入 ramCache
  2. 写入 write queue,它是一个阻塞队列 ArrayBlockingQueue。入队 queue.offer() 失败的时候,将失败次数记录写到:failedBlockAdditions
 RAMQueueEntry re =
        new RAMQueueEntry(cacheKey, cachedItem, accessCount.incrementAndGet(), inMemory);
    if (ramCache.putIfAbsent(cacheKey, re) != null) {
      return;
    }
    int queueNum = (cacheKey.hashCode() & 0x7FFFFFFF) % writerQueues.size();
    BlockingQueue<RAMQueueEntry> bq = writerQueues.get(queueNum);
    boolean successfulAddition = false;
    if (wait) {
      try {
        successfulAddition = bq.offer(re, DEFAULT_CACHE_WAIT_TIME, TimeUnit.MILLISECONDS);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      }
    } else {
      successfulAddition = bq.offer(re);
    }
    if (!successfulAddition) {
      ramCache.remove(cacheKey);
      failedBlockAdditions.incrementAndGet();
    }

所以 failedBlockAdditions 是写缓存失败次数,具体是写入 write 队列失败的次数。

问题1.1 :为什么会写入队列失败?有何优化的方法?
查看 ArrayBlockingQueue offer() 方法源码,当队列满了,等待了 timeout 时间后,队列依然是满的,返回 false,入队列失败。
所以 failedBlockAdditions 一般发生在出现大量请求,导致写缓存繁忙的时候。与之的对应的参数有两个:

  1. write 线程个数:hbase.bucketcache.writer.threads (默认3)
  2. 每个write 线程队列长度配置:hbase.bucketcache.writer.queuelength(默认32)

适当调大这两个参数可以缓解此问题。

问题2:什么是 hitCachingCount?与 hits 有什么区别?hitRatio 与 cachingHitsRatio 的区别?

hits 是中的缓存命中次数。

hitCachingCount 统计总的缓存命中次数,但排除显示设定不会更新缓存的请求(setBlockCache(false)),它是 HBASE-2253 新加的统计指标,代码如下。目的是为了更精确的统计显示使用缓存的命中率。

/**
* The number of getBlock requests that were cache hits, but only from
* requests that were set to use the block cache.  This is because all reads
* attempt to read from the block cache even if they will not put new blocks
* into the block cache.  See HBASE-2253 for more information.
*/
private final AtomicLong hitCachingCount = new AtomicLong(0);

这里需要了解一下 hbase 的 setBlockCache 配置。
所有的读请求,都会先请求缓存。默认配置下,读请求(get、scan),如果未命中缓存会更新数据到缓存。
但有时候为了性能优化,针对 mr 或者大 scan 用户会设置不缓存数据。设置方式为:scan.setBlockCache(false)。注意,即使设置了 setBlockCache = false ,读请求第一时间也会先查缓存。

所以 hitCachingCount 是统计总的缓存命中次数,但排除显示设定不会更新缓存的请求。

举个例子:
access: 100 次请求,总命中缓存次数 hits:90 次 hitRatio = 90%
其中 cachingAccesses = 80, hitCachingCount = 78,cachingHitsRatio=78/80 = 97.5%
access =100,cachingAccesses = 80,其中有 20 次请求来自于非缓存请求,例如 mr 或者大 scan 请求。
所以,用户关心的真是缓存命中率为: 97.5%,而不是 90%。

问题3 :IOhitsPerSecond、IOTimePerHit 是什么?
这个是读缓存相关性能指标:

  • IOhitsPerSecond: 每秒 bucket io hit 次数
  • IOTimePerHit :每次 IO 的耗时

通过源码了解到,读缓存的流程:

  1. 首先从 RAMCache 中查找。对于还没有来得及写入到 bucket 的缓存 block,一定存储在RAMCache 中;
  2. 如果在 RAMCache 中没有找到,再在 BackingMap 中根据 blockKey 找到对应物理偏移地址offset;
  3. 根据物理偏移地址 offset 可以直接从内存中查找对应的 block 数据;

第一步,查找 RAMCache,它是一个 ConcurrentMap,如果命中相当于直接命中内存。
第二步,通过 ioEngine 去读 bucketcache 缓存,所以通过这一步命中的缓存会记录 IO 耗时,这里的 IO 耗时包括:通过 Bytebuffer 进行数据读取、读取后的数据反序列化耗时。

问题4:eviction 是什么?什么时候会发生 eviction?
eviction 字面意思是驱逐,当缓存使用空间 > acceptableSize()或 一种类型的 block 无法申请的时候,需要释放缓存空间,通过 LRU 算法淘汰,驱逐 block。
acceptableSize = bucketc ache 配置总大小*0.95

Free the space if the used size reaches acceptableSize() or one size block
couldn't be allocated. When freeing the space, we use the LRU algorithm and
ensure there must be some blocks evicted

问题 4.1: evictions=14844, evicted=1384179287, evictedPerRun=93248.40625 分别是什么?
eviction:发生 evication 的次数
evicted:总的 evict block 的个数
evictedPerRun :evicted/eviction

问题 5 :bucket cache size 怎么配置的? 使用情况如何?
bucket cache size 配置的分布,从小到大是:(4+1)K,(8+1)K ...(64+1)K 到 (2048+1)K
通过 HBase UI 查看 bucketcache 分布情况,当前申请的 bucket cache size 都是 65K,并且很多 bucket 存储使用率并不高,说明 block 大都是小数据。

问题 5.1 :为什么申请的大都是 (64+1)k 的 bucket ?有什么优化点
这里由于 HBase 默认的 block size 是 64K,说明读请求数据大小大多在 64K block 内。并且,很多 bucket 存储使用率并不高,说明 block 大都是小数据。

这里有什么可以优化的点呢?
可以尝试将表的 blocksize 调小。例如 32k。

参考 HFile 代码注释,HBase 推荐的大小是 8K-1M。设置大有利于顺序扫描,比如 Scan, 但不适合随机查询,想想看,每一次随机查询可能都需要你去解压缩一个大的数据块。

小的数据块适合随机的查询,但是需要更多的内存来保存数据块的索引(Data Index),而且创建文件的时候也可能比较慢,因为在每个数据块的结尾我们都要把压缩的数据流 Flush 到文件中去(引起更多的 Flush 操作)。并且由于压缩器内部还需要一定的缓存,最小的数据块大小应该在 20KB – 30KB 左右。设置小有利于随机读。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容