HBase 性能调优第一弹:内存篇

这是使用 HBase 最不可避免的一个话题,就是 HBase 的性能调优,而且通常建立在我们对 HBase 内部运行机制比较了解的基础上进行的,因此无论怎么说,调优这块都是一个相对复杂的事情。这一篇我们先来介绍与 HBase 内存最相关的调优内容。

1. 合理配置 JVM 内存

这里首先涉及 HBase 服务的堆内存设置。一般刚部署的 HBase 集群,默认配置只给 Master 和 RegionServer 分配了 1G 的内存,RegionServer 中 MemStore 默认占 0.4 即 400MB 左右的空间,而一个 MemStore 刷写阈值默认 128M,所以一个 RegionServer 也就能正常管理 3 个Region,多了就可能会产生小文件了,另外也容易发生 Full GC。因此建议合理调整 Master 和 RegionServer 的内存,比如:

export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS -Xms8g -Xmx8g"
export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS -Xms32g -Xmx32g"

这里也要根据实际集群资源进行配置,另外要牢记至少留 10% 的内存给操作系统使用。

2. 选择合适的 GC 策略

另一个重要方面是 HBase JVM 的 GC 优化,其实 HBase 读写路径上的很多设计都是围绕 GC 优化做的。选择合适的 GC 策略非常重要,对于 HBase 而言通常有两种可选 GC 方案:

  • ParallelGC 和 CMS 组合

  • G1GC

而 CMS 和 G1 有什么区别呢?

CMS 避免不了 Full GC,而且 Full GC 场景下会通过一次串行的完整垃圾收集来回收碎片化的内存,这个过程通常会比较长,应用线程会发生长时间的 STW 停顿,不响应任何请求;而 G1 适合大内存的场景,通过把堆内存划分为多个 Region(不是 HBase 中的 Region),然后对各个 Region 单独进行 GC,这样就具有了并行整理内存碎片的功能,可以最大限度的避免 Full GC 的到来,提供更加合理的停顿时间。

由于 Master 只是做一些管理操作,实际处理读写请求和存储数据的都是 RegionServer 节点,所以一般内存问题都出在 RegionServer 上。

这里给的建议是,小堆(4G及以下)选择 CMS,大堆(32G及以上)考虑用 G1,如果堆内存介入 4~32G 之间,可自行测试下两种方案。剩下来的就是 GC 参数调优了,这一块也要合理配置加上实际测试,后面再单独聊这块。

3. 开启 MSLAB 功能

这是 HBase 自己实现了一套以 MemStore 为最小单元的内存管理机制,称为 MSLAB(MemStore-Local Allocation Buffer),主要作用是为了减少内存碎片化,改善 Full GC 发生的情况。

MemStore 会在内部维护一个 2M 大小的 Chunk 数组,当写入数据时会先申请 2M 的 Chunk,将实际数据写入该 Chunk中,当该 Chunk 满了以后会再申请一个新的 Chunk。这样 MemStore Flush 后会达到粗粒度化的内存碎片效果,可以有效降低 Full GC 的触发频率。

HBase 默认是开启 MSLAB 功能的,和 MSLAB 相关的配置包括:

  • hbase.hregion.memstore.mslab.enabled:MSLAB 开关,默认为 true,即打开 MSLAB。

  • hbase.hregion.memstore.mslab.chunksize:每个 Chunk 的大 小,默认为 2MB,建议保持默认值。

  • hbase.hregion.memstore.chunkpool.maxsize:内部 Chunk Pool 功能,默认为 0 ,即关闭 Chunk Pool 功能。设置为大于 0 的值才能开启,取值范围为 [0,1],表示 Chunk Pool 占整个 MemStore 内存大小的比例。

  •  hbase.hregion.memstore.chunkpool.initialsize:表示初始化时申请多少个 Chunk 放到 Chunk Pool 中,默认为 0,即初始化时不申请 Chuck,只在写入数据时才申请。

  • hbase.hregion.memstore.mslab.max.allocation:表示能放入 MSLAB 的最大单元格大小,默认为 256KB,超过该大小的数据将从 JVM 堆分配空间而不是 MSLAB。

出于性能优化考虑,建议检查相关配置,确保 MSLAB 处于开启状态。

4. 考虑开启 BucketCache

这块涉及到读缓存 BlockCache 的策略选择。首先,BlockCache 是 RegionServer 级别的,一个 RegionServer 只有一个 BlockCache。BlockCache 的工作原理是读请求会首先检查 Block 是否存在于 BlockCache,存在就直接返回,如果不存在再去 HFile 和 MemStore 中获取,返回数据时把 Block 缓存到 BlockCache 中,后续同一请求或临近查询可以直接从 BlockCache 中获取,避免过多的昂贵 IO 操作。BlockCache 默认是开启的。

目前 BlockCache 的实现方案有三种:

LRUBlockCache

最早的 BlockCache 方案,也是 HBase 目前默认的方案。LRU 是 Least Recently Used 的缩写,称为近期最少使用算法。LRUBlockCache 参考了 JVM 分代设计的思想,采用了缓存分层设计。

LRUBlockCache 将整个 BlockCache 分为 single-access(单次读取区)、multi-access(多次读取区)和 in-memory 三部分,默认分别占读缓存的25%、50%、25%。其中设置 IN_MEMORY=true 的列族,Block 被读取后才会直接放到 in-memory 区,因此建议只给那些数据量少且访问频繁的列族设置 IN_MEMORY 属性。另外,HBase 元数据比如 meta 表、namespace 表也都缓存在 in-memory 区。

SlabCache

HBase 0.92 版本引入的一种方案,起初是为了避免 Full GC 而引入的一种堆外内存方案,并与 LRUBlockCache 搭配使用,后来发现它对 Full GC 的改善很小,以至于这个方案基本被弃用了。

BucketCache

HBase 0.96 版本引入的一种方案,它借鉴了 SlabCache 的设计思想,是一种非常高效的缓存方案。实际应用中,HBase 将 BucketCache 和 LRUBlockCache 搭配使用,称为组合模式(CombinedBlockCahce),具体地说就是把不同类型的 Block 分别放到 LRUBlockCache 和 BucketCache 中。

HBase 会把 Index Block 和 Bloom Block 放到 LRUBlockCache 中,将 Data Block 放到 BucketCache 中,所以读取数据会去 LRUBlockCache 查询一下 Index Block,然后再去 BucketCache 中查询真正的数据。

BucketCache 涉及的常用参数有:

  • hbase.bucketcache.ioengine:使用的存储介质,可设置为 heap、offheap 或 file,其中 heap 表示空间从JVM堆中申请,offheap 表示使用 DirectByteBuffer 技术实现堆外内存管理,file 表示使用类似 SSD 等存储介质缓存数据。默认值为空,即关闭 BucketCache,一般建议开启 BucketCache。此外,HBase 2.x 不再支持 heap 选型。

  • hbase.bucketcache.combinedcache.enabled:是否打开 CombinedBlockCache 组合模式,默认为 true。此外,HBase 2.x 不再支持该参数。

  • hbase.bucketcache.size:BucketCache 大小,取值有两种,一种是[0,1]之间的浮点数值,表示占总内存的百分比,另一种是大于1的值,表示占用内存大小,单位 MB。

根据上面的分析,一般建议开启 BucketCache,综合考虑成本和性能,建议比较合理的介质是:LRUBlockCache 使用内存,BuckectCache 使用SSD,HFile 使用机械磁盘。

5. 合理配置读写缓存比例

HBase 为了优化性能,在读写路径上分别设置了读缓存和写缓存,参数分别是 hfile.block.cache.size 与 hbase.regionserver.global.memstore.size,默认值都是 0.4,表示读写缓存各占 RegionServer 堆内存的 40%。 

在一些场景下,我们可以适当调整两部分比例,比如写多读少的场景下我们可以适当调大写缓存,让 HBase 更好的支持写业务,相反类似,总之两个参数要配合调整。

6. 总结

本文总结了与 HBase 内存最相关的调优内容,主要包括 JVM 内存大小设置,选择合适的 GC 策略,建议开启 MSLAB 与 BucketCache,以及合理配置读写缓存比例等内容,希望通过本文我们对于 HBase 性能调优有了一定的认识。

欢迎大家留言讨论

???? ???? ????

往期推荐

HBase二次开发之搭建HBase调试环境,如何远程debug HBase源代码

【生活现场】从洗袜子到HBase存储原理解析

HBase的ACL说明

HBase配置AES加密

HBase原理(一):架构理解

如何将Hive与HBase整合联用

Python生成HBase 10w+ 条数据说明

HBase应用(一):数据批量导入说明

HBase 集成 Phoenix 构建二级索引实践

HBase漫谈 | HBase分区过多影响&合理分区数量

扫一扫,我们的故事就开始了。

如果这篇文章对你有所启发,点赞、转发都是一种支持!

另外公众号改变了推送规则,大家看文章不要忘记点击最下方的在看,点赞按钮,这样微信自动识别为常看公众号,否则很可能推送的文章可能淹没在别的文章找不到,谢谢大家

让我知道你在看

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值