返回 登录
0

网易视频云:HBase最佳实践-内存规划

阅读1144

网易视频云是网易倾力打造的一款基于云计算的分布式多媒体处理集群和专业音视频技术,为客户提供稳定流畅、低时延、高并发的视频直播、录制、存储、转码及点播等音视频的PASS服务。在线教育、远程医疗、娱乐秀场、在线金融等各行业及企业用户只需经过简单的开发即可打造在线音视频平台。现在,网易视频云与大家分享一下HBase最佳实践-内存规划.

线上HBase集群应该如何进行参数配置?这其实是很多HBase初学者在实践环节都可能会遇到的问题,有些人会选择默认配置,有些人会选择其他公司的推荐配置;诚然,这样的参数配置在大多数情况下都能正常工作,但性能却未必最佳、资源未必都能被合理利用。本文结合笔者的实践经验,针对不同应用场景,对多种工作模式下的参数进行详细说明,并结合相关示例对集群规划中最核心模块-内存规划进行介绍。一方面希望读者能够了解HBase内存相关知识细节,另一方面能够将这些知识应用于实践、不断对集群进行优化。

HBase中内存规划直接涉及读缓存BlockCache、写缓存MemStore,影响系统内存利用率、IO利用率等资源以及读写性能等,重要性不言而喻。主要配置也是针对BlockCache和MemStore进行,然而针对不同业务类型(简单说来主要包括读多写少型和写多读少型),内存的相关配置却完全不同。再者,对于读缓存BlockCache,线上一般会有两种工作模式:LRUBlockCache和BucketCache,不同工作模式下的相关配置也不尽相同。为了比较完整的说明不同应用场景以及不同缓存工作模式的内存规划,下文会分分别介绍两个案列:读多写少型+BucketCache,写多读少型+LRUBlockCache。
需要说明的是,业务类型和读缓存工作模式之间没有任何直接的关联。业务到底使用BucketCache还是使用LRUBlockCache,只和分配给RegionServer的内存大小有关。一般而言,如果HBASE_HEAPSIZE > 20G,选择BucketCache,否则选择LRUBlockCache(参考hortonworks文档),理论依据可以参考这里。

案例一:写多读少型 + LRUBlockCache
内存分布图
在详细说明具体的容量规划前,首先需要明确LRUBlockCache模式下的内存分布图,如下图所示:

图中分配给RegionServer进程的内存就是JVM内存,主要分为三部分:LRUBlockCache,用于读缓存;MemStore,用于写缓存;Other,用于RS运行所必须的其他对象;
内存规划思路
了解了BucketCache模式下的内存分布图之后,我们具体来分析如何规划内存,首先列出来基本条件:
a. 整个物理机内存:96G
b. 业务负载分布:30%读,70%写
接下来将问题一步一步分解,从上至下按照逻辑对内存进行规划:
(1) 系统内存基础上如何规划RS内存?
这个问题需要根据自身服务器情况决定,一般情况下,在不影响其他服务的情况下,越大越好。我们目前设置为64G,为系统内存的2/3。
(2) 如何设置LRUBlockCache、MemStore?
确定RegionServer总内存之后,接下来分别规划LRUBlockCahce和MemStore的总内存。在此需要考虑两点:在写多读少的业务场景下,写缓存显然应该分配更多内存,读缓存相对分配更少;HBase在此处有个硬规定:LRUBlockCache + MemStore < 80% * JVM_HEAP,否则RS无法启动。
推荐内存规划:MemStore = 45% * JVM_HEAP = 64G * 45% = 28.8G ,LRUBlockCache = 30% * JVM_HEAP = 64G * 30% = 19.2G;默认情况下Memstore为40% * JVM_HEAP,而LRUBlockCache为25% * JVM_HEAP
图片描述

案例二:读多写少型 + BucketCache
内存分布图
与LRUBlockCache模式相比,BucketCache模式下的内存分布图会更加复杂,如下图所示:

图片描述
如图,整个RegionServer内存(Java进程内存)分为两部分:JVM内存和堆外内存。其中JVM内存中LRUBlockCache和堆外内存BucketCache一起构成了读缓存CombinedBlockCache,用于缓存读到的Block数据,其中LRUBlockCache用于缓存元数据Block,BucketCache用于缓存实际用户数据Block;MemStore用于写流程,缓存用户写入KeyValue数据;还有部分用于RegionServer正常运行所必须的内存;
内存规划思路
和案例一相同,本案例中物理机内存也是96G,不过业务类型为读多写少:70%读+30%写
因为BucketCache模式下内存分布图相对复杂,我们使用如下表格一步一步对内存规划进行解析:
图片描述
计算修正
看到这里,可能很多仔细的朋友就会疑问,案例一不是说过HBase有一个硬规定么:LRUBlockCache + MemStore < 80% * JVM_HEAP,否则RS无法启动。不错,HBase确实有这样一个规定,这个规定的本质是为了在内存规划的时候能够给除过写缓存和读缓存之外的其他对象留够至少20%的内存空间。那按照上述计算方式能不能满足这个硬规定呢,LRU + MemStore / JVM_HEAP = 3G + 25G / 35G = 28G / 35G = 80% ,刚好等于阈值 80%,为了更加保险,建议这个值在70%~75%之间,因此需要对计算值进行简单的修正,适量增大JVM_HEAP值(增大至40G),BucketCache减少到24G(CombinedBlockCache需调整到26G)。调整之后,LRU + MemStore / JVM_HEAP = 3G + 25G / 40G = 28G / 40G = 70%
图片描述

按照上述介绍设置之后,所有关于内存相关的配置基本就完成了。但是需要特别关注一个参数hfile.block.cache.size,这个参数在本案例中并不需要设置,没有任何意义。但是HBase的硬规定却是按照这个参数计算的,这个参数的值加上hbase.regionserver.global.memstore.upperLimit的值不能大于0.8,上文提到hbase.regionserver.global.memstore.upperLimit值设置为0.6,因此,hfile.block.cache.size必须设置为一个小于0.2的任意值。hbase.bucketcache.ioengine表示bucketcache设置为offheap模式;hbase.bucketcache.size表示所有读缓存占用内存大小,该值可以为内存真实值,单位为M,也可以为比例值,表示读缓存大小占JVM内存大小比例。如果为内存真实值,则为26G,即26624M。而如果是比例值,则计算应为 26G / 40G = 65%,设为0.65即可;hbase.bucketcache.percentage.in.combinedcache参数表示用于缓存用户数据块的内存(堆外内存)占所有读缓存的比例,设为0.90;
至此,关于HBase集群的内存规划经过两个案例的分析到此就要结束了,希望看官能够理解整个分析的思路。结合自己的应用场景以及内存使用模式对内存进行规划。本文也只是笔者个人见解,如果有任何意见可以相互交流讨论

评论