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

简介: 这是使用 HBase 最不可避免的一个话题,就是 HBase 的性能调优,而且通常建立在我们对 HBase 内部运行机制比较了解的基础上进行的,因此无论怎么说,调优这块都是一个相对复杂的事情。这一篇我们先来介绍与 HBase 内存最相关的调优内容。1. 合理配置 JVM 内存这里首先涉及 HBase 服务的堆内存设置。一般刚部署的 HBase 集群,默认配置只给 Master 和 RegionServer 分配了 1G 的内存,RegionServer 中 MemStore 默认占 0.4 即 400MB 左右的空间,而一个 MemStore 刷写阈值默认 128M,所以一个 Regi

这是使用 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% 的内存给操作系统使用。

  1. 选择合适的 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 参数调优了,这一块也要合理配置加上实际测试,后面再单独聊这块。

  1. 开启 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 处于开启状态。

  1. 考虑开启 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 使用机械磁盘。

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

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

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

  1. 总结

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

相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
  相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情: https://cn.aliyun.com/product/hbase   ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
存储 缓存 监控
|
1月前
|
监控 JavaScript 算法
如何使用内存监控工具来定位和解决Node.js应用中的性能问题?
总之,利用内存监控工具结合代码分析和业务理解,能够逐步定位和解决 Node.js 应用中的性能问题,提高应用的运行效率和稳定性。需要耐心和细致地进行排查和优化,不断提升应用的性能表现。
181 77
|
1月前
|
存储 缓存 JavaScript
如何优化Node.js应用的内存使用以提高性能?
通过以上多种方法的综合运用,可以有效地优化 Node.js 应用的内存使用,提高性能,提升用户体验。同时,不断关注内存管理的最新技术和最佳实践,持续改进应用的性能表现。
122 62
|
28天前
|
存储 缓存 监控
如何使用内存监控工具来优化 Node.js 应用的性能
需要注意的是,不同的内存监控工具可能具有不同的功能和特点,在使用时需要根据具体工具的要求和操作指南进行正确使用和分析。
67 31
|
25天前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
64 7
|
26天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
57 1
|
1月前
|
缓存 Ubuntu Linux
Linux环境下测试服务器的DDR5内存性能
通过使用 `memtester`和 `sysbench`等工具,可以有效地测试Linux环境下服务器的DDR5内存性能。这些工具不仅可以评估内存的读写速度,还可以检测内存中的潜在问题,帮助确保系统的稳定性和性能。通过合理配置和使用这些工具,系统管理员可以深入了解服务器内存的性能状况,为系统优化提供数据支持。
38 4
|
1月前
|
Arthas 监控 Java
JVM进阶调优系列(9)大厂面试官:内存溢出几种?能否现场演示一下?| 面试就那点事
本文介绍了JVM内存溢出(OOM)的四种类型:堆内存、栈内存、元数据区和直接内存溢出。每种类型通过示例代码演示了如何触发OOM,并分析了其原因。文章还提供了如何使用JVM命令工具(如jmap、jhat、GCeasy、Arthas等)分析和定位内存溢出问题的方法。最后,强调了合理设置JVM参数和及时回收内存的重要性。
|
1月前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
52 6
|
1月前
|
监控 安全 程序员
如何使用内存池池来优化应用程序性能
如何使用内存池池来优化应用程序性能