本套技术专栏是作者(秦凯新)平时工作的总结和升华,通过从真实商业环境抽取案例进行总结和分享,并给出商业应用的调优建议和集群环境容量规划等内容,请持续关注本套博客。版权声明:禁止转载,欢迎学习。QQ邮箱地址:[email protected],如有任何学术交流,可随时联系。
网上的Hbase调优资料参差不齐,实在是不忍卒读,有些都是拼凑且版本过时的东西,我这里决定综合所有优质资源进行整合,写一份最全,最有深度,不过时的技术博客。辛苦成文,各自珍惜,谢谢!
1 HBase生产环境集群调优关键点
- HBase中内存规划直接涉及读缓存BlockCache、写缓存MemStore,影响系统内存利用率、IO利用率等资源以及读写性能等,重要性不言而喻。因此HBase生产环境集群调优主要也是针对BlockCache和MemStore进行的。
- 对于读缓存BlockCache,线上一般会有两种工作模式:LRUBlockCache和BucketCache
- 读多写少型+BucketCache
- 写多读少型+LRUBlockCache
- 业务到底使用BucketCache还是使用LRUBlockCache,只和分配给RegionServer的内存大小有关。一般而言,如果HBASE_HEAPSIZE > 20G,选择BucketCache,否则选择LRUBlockCache。
2 读多写少型+BucketCache
-
对于读多写少型+BucketCache架构:整个RegionServer内存(Java进程内存)分为两部分:JVM内存和堆外内存。其中JVM内存中LRUBlockCache和堆外内存BucketCache一起构成了读缓存CombinedBlockCache,用于缓存读到的Block数据,其中LRUBlockCache用于缓存元数据Block,BucketCache用于缓存实际用户数据Block;MemStore用于写流程,缓存用户写入KeyValue数据;还有部分用于RegionServer正常运行所必须的内存;
-
本例中物理机内存也是96G,不过业务类型为读多写少:70%读+30%写:
-
官方要求:RUBlockCache + MemStore < 80% *JVM_HEAP,否则RS无法启动。这个规定的本质是为了在内存规划的时候能够给除过写缓存和读缓存之外的其他对象留够至少20%的内存空间。那按照上述计算方式能不能满足这个硬规定呢?
(LRU + MemStore) / JVM_HEAP = 3.2G + 19.2G / 35.2G = 22.4G / 35.2G = 63.6% 复制代码
-
上述结果远小于80%。因此需要对计算值进行简单的修正,适量减少JVM_HEAP值(减少至30G),增大Memstore到20G。因为JVM_HEAP减少了,堆外内存就需要适量增大,因此将BucketCache增大到30G。修正之后,
(LRU + MemStore) / JVM_HEAP = (3.2G + 20G )/ 30G = 23.2G / 30G = 77% 复制代码
-
参数配置:
(1)设置JVM参数如下: -XX:SurvivorRatio=2 -XX:+PrintGCDateStamps -Xloggc:$HBASE_LOG_DIR/gc-regionserver.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=1 -XX:GCLogFileSize=512M -server -Xmx40g -Xms40g -Xmn1g -Xss256k -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC (2)hbase-site.xml中MemStore相关参数设置如下: hbase.regionserver.global.memstore.upperLimit参数被废弃了,改用 hbase.regionserver.global.memstore.size默认是0.4 根据upperLimit参数的定义,结合上述内存规划数据可计算出 global.memstore.size = 20G / 30G = 66%。 因此hbase.regionserver.global.memstore.size参数设置为0.66,lowerLimit设置为0.60 <property> <name>hbase.regionserver.global.memstore.size</name> <value>0.66</value> </property> <property> <name>hbase.regionserver.global.memstore.lowerLimit</name> <value>0.60</value> </property> (3) hbase-site.xml中CombinedBlockCache相关参数设置如下: hbase.bucketcache.ioengine表示bucketcache设置为offheap模式;hbase.bucketcache.size表示所有读缓存占用内存大小, 该值可以为内存真实值,单位为M,也可以为比例值,表示读缓存大小占JVM内存大小比例。如果为内存真实值,则为34G,即34816。 hbase.bucketcache.percentage.in.combinedcache 参数被废弃了 <property> <name>hbase.bucketcache.ioengine</name> <value>offheap</value> </property> <property> <name>hbase.bucketcache.size</name> <value>34816</value> </property> 复制代码
3 写多读少型 + LRUBlockCache
-
整个物理机内存:96G
-
业务负载分布:30%读,70%写
-
系统内存基础上如何规划RS内存,一般情况下,在不影响其他服务的情况下,越大越好。我们目前设置为64G,为系统内存的2/3
(1)如何设置LRUBlockCache、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 (2)设置JVM参数如下: -XX:SurvivorRatio=2 -XX:+PrintGCDateStamps -Xloggc:$HBASE_LOG_DIR/gc-regionserver.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=1 -XX:GCLogFileSize=512M -server -Xmx64g -Xms64g -Xmn2g -Xss256k -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC (3)hbase-site.xml中MemStore相关参数设置如下: base.regionserver.global.memstore.upperLimit参数被废弃了,改用 hbase.regionserver.global.memstore.size默认是0.4 hbase.regionserver.global.memstore.size设置为0.45,hbase.regionserver.global.memstore.lowerLimit设置为0.40 hbase.regionserver.global.memstore.size表示RegionServer中所有MemStore占有内存在JVM内存中的比例上限。如果所占比例超过这个值,RS写请求就会阻塞,RS会首先将所有Region按照MemStore大小排序,并按照由大到小的顺序依次执行flush,直至所有MemStore内存总大小小于hbase.regionserver.global.memstore.lowerLimit,一般lowerLimit比upperLimit小5%。 <property> <name>hbase.regionserver.global.memstore.size</name> <value>0.45</value> </property> <property> <name>hbase.regionserver.global.memstore.lowerLimit</name> <value>0.4</value> </property> (4) hbase-site.xml中LRUBlockCache相关参数设置如下: hfile.block.cache.size表示LRUBlockCache占用内存在JVM内存中的比例,因此设置为0.3 <property> <name>hfile.block.cache.size</name> <value>0.3</value> </property> 复制代码
总结
本文参考了一篇非常好的博客《HBase最佳实践-内存规划》,只可惜版本太老,导致部分参数已经废弃,本文进行了修正,辛苦成文,各自珍惜,谢谢!
秦凯新 于深圳 20181128200