版权声明:转载请注明出处! https://blog.csdn.net/ddxygq/article/details/86418081
hbase是个比较吃内存的大数据组件,虽然数据存在hdfs中,但是不像mysql或者elasearch那样有索引的优势,只能用内存缓存数据来实现快速存取。
hbase安装时候,通常都需要修改配置文件,默认配置通常是8G内存的配置。
配置文件有问题的话,后果是:hbase集群启动,直接报错,启动失败。所以说,一个好的hbase内存配置,很重要。
数据组hbase好端端的,老是不够,然后非常协调的整个集群挂了,后来发现是机器64G内存升到96G的时候,我想当然的把32G堆内存改为64G,导致分配不到资源却不进行GC,一直向系统拿内存,集群就挂了。
后来,我们重新规划了一下内存,一直很坚挺。我们集群版本是这样的:
hadoop 3.0
hbase 2.0.3
注意:hbase1.x与2.x区别很大,无论是flush、compact,还是split上面,所以这里需要强调一下,版本是2.0.3,网上很多博客讲的是1.x版本的,2.x有很大改变,属于重大版本变更。hbase2.x相比1.x确实有很大的改变,比如:尽量使用offheap对外内存,官方还有一种说法,使用断电不丢数据的内存,来替换掉wal机制。版本很重要,区别很大。
这里主要介绍几个概念:
compact
flush
内存规划
compaction
HBase compaction主要是为了压缩存储空间,提高读写速度,根据合并规模将Compaction分为了两类:MinorCompaction和MajorCompaction
-
Minor Compaction是指选取一些小的、相邻的StoreFile将他们合并成一个更大的StoreFile,在这个过程中不会处理已经Deleted或Expired的Cell。一次Minor Compaction的结果是更少并且更大的StoreFile。
-
Major Compaction是指将所有的StoreFile合并成一个StoreFile,这个过程还会清理三类无意义数据:被删除的数据、TTL过期数据、版本号超过设定版本号的数据。另外,一般情况下,Major Compaction时间会持续比较长,整个过程会消耗大量系统资源,对上层业务有比较大的影响。因此线上业务都会将关闭自动触发Major Compaction功能,改为手动在业务低峰期触发。
minor compaction通常会由memstore flush,线程定期检查触发。major compaction通常会由手动触发,可以通过参数,hbase.hregion.majorcompaction设置为0即可,默认时间一天86400000。
手动compact
进入hbase shell执行手动压缩命令。
minor compaction
hbase(main):009:0>help"compact"
Compactallregionsinpassedtableorpassaregionrow
tocompactanindividualregion.Youcanalsocompactasinglecolumn
familywithinaregion.
Youcanalsosetcompacttype,"NORMAL"or"MOB",anddefaultis"NORMAL"
Examples:
Compactallregionsinatable:
hbase>compact'ns1:t1'
hbase>compact't1'
Compactanentireregion:
hbase>compact'r1'
Compactonlyacolumnfamilywithinaregion:
hbase>compact'r1','c1'
Compactacolumnfamilywithinatable:
hbase>compact't1','c1'
Compacttablewithtype"MOB"
hbase>compact't1',nil,'MOB'
Compactacolumnfamilyusing"MOB"typewithinatable
hbase>compact't1','c1','MOB'
major compaction
hbase(main):003:0>help'major_compact'
Runmajorcompactiononpassedtableorpassaregionrow
tomajorcompactanindividualregion.Tocompactasingle
columnfamilywithinaregionspecifytheregionname
followedbythecolumnfamilyname.
Examples:
Compactallregionsinatable:
hbase>major_compact't1'
hbase>major_compact'ns1:t1'
Compactanentireregion:
hbase>major_compact'r1'
Compactasinglecolumnfamilywithinaregion:
hbase>major_compact'r1','c1'
Compactasinglecolumnfamilywithinatable:
hbase>major_compact't1','c1'
Compacttablewithtype"MOB"
hbase>major_compact't1',nil,'MOB'
Compactacolumnfamilyusing"MOB"typewithinatable
hbase>major_compact't1','c1','MOB'
flush
hbase写数据,一般先写wal,确认成功后,再写memstore,每个列族有一个memstore,当一个region所有family memstore大小之和达到一定大小(hbase.regionserver.global.memstore.size),这个值通常是默认128M,就会flush,当然一个family的memstore大小达到这个值也会flush的,这样做也是为了提高读写的效率。在2.0+版中,memstore其实是有一个可变的memstore和许多不可变的memstore组成,直接在内存中进行compaction,如果flush成HFile,再compaction,会占用大量磁盘和网络IO,这是一个改进。
内存规划
hbase内存规划,需要结合实际业务,分为读多写少,还是读少写多,我们的业务是读少写多。通常,我们会错误估算了写,compaction、split、flush都要涉及到写。这里是我们业务读多写少的内存规划。主要是常见的64G机器与96G机器。
对BlockCache策略一直有这样的观点:RS内存在20G以内的就选择LRUBlockCache,大于20G的就选择BucketCache中的Offheap模式。接下来所有的相关配置都基于BucketCache的offheap模型进行说明。
机器64G内存规划
序号 |
步骤 |
原理 |
计算公式 |
计算值 |
修正值 |
---|
A |
规划RS总内存 |
在系统内存允许且不影响其他服务的情况下,越多越好。64G内存,预留8G即可 |
64G - 8G |
56G |
56G |
B |
规划读缓存 CombinedBlockCache |
整个RS内存分为三部分:读缓存、写缓存、其他。基本按照5 : 4 : 1的分配原则。读缓存设置为整个RS内存的50% |
A(56G) * 50% |
28G |
28G |
B1 |
规划读缓存LRU部分 |
LRU部分主要缓存数据块元数据,数据量相对较小。设置为整个读缓存的10% |
B(28G)*10% |
2.8G |
3G |
B2 |
规划读缓存BucketCache部分 |
BucketCache部分主要缓存用户数据块,数据量相对较大。设置为整个读缓存的90% |
B(28G)*90% |
25.2G |
24G |
C |
规划写缓存MemStore |
整个RS内存分为三部分:读缓存、写缓存、其他。基本按照5:4:1的分配原则。写缓存设置为整个RS内存的40% |
A(56G) * 40% |
22.4G |
22G |
D |
设置JVM_HEAP |
RS总内存大小 减去 堆外内存大小 |
A – B2 |
30.8G |
32G
|
注意
LRUBlockCache + MemStore < 80% * JVM_HEAP
hbase-env.sh
-Xmx32g -Xms32g -Xmn1g -Xss256k -XX:MaxPermSize=256m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC
hbae-site.xml
<property>
<name>hbase.regionserver.global.memstore.upperLimit</name>
<value>0.60</value>
</property>
<property>
<name>hbase.regionserver.global.memstore.lowerLimit</name>
<value>0.55</value>
</property>
<property>
<name>hfile.block.cache.size</name>
<value>0.19</value>
</property>
<property>
<name>hbase.bucketcache.ioengine</name>
<value>offheap</value>
</property>
<property>
<name>hbase.bucketcache.size</name>
<value>24576</value>
</property>
<property>
<name>hbase.bucketcache.percentage.in.combinedcache</name>
<value>0.90</value>
</property>
96G内存规划
序号 |
步骤 |
原理 |
计算公式 |
计算值 |
修正值 |
---|
A |
规划RS总内存 |
在系统内存允许且不影响其他服务的情况下,越多越好。96G内存,预留8G即可 |
96G - 8G |
88G |
88G |
B |
规划读缓存 CombinedBlockCache |
整个RS内存分为三部分:读缓存、写缓存、其他。基本按照5 : 4 : 1的分配原则。读缓存设置为整个RS内存的50% |
A(88G) * 50% |
44G |
44G |
B1 |
规划读缓存LRU部分 |
LRU部分主要缓存数据块元数据,数据量相对较小。设置为整个读缓存的10% |
B(44G)*10% |
4.4G |
4G |
B2 |
规划读缓存BucketCache部分 |
BucketCache部分主要缓存用户数据块,数据量相对较大。设置为整个读缓存的90% |
B(44G)*90% |
39.6G |
39G |
C |
规划写缓存MemStore |
整个RS内存分为三部分:读缓存、写缓存、其他。基本按照5:4:1的分配原则。写缓存设置为整个RS内存的40% |
A(88G) * 40% |
35.2G |
35G |
D |
设置JVM_HEAP |
RS总内存大小 减去 堆外内存大小 |
A – B2 |
49G |
49G |
hbase-env.sh
export HBASE_HEAPSIZE=32768
#export master_heapsize=65536
export regionserver_heapsize=50176
export HBASE_REGIONSERVER_OPTS="-Xmx49g -Xms49g -Xmn2g -Xss256k -XX:MaxPermSize=256m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC"
hbase-site.xml
<!--节点上所有region的memstore之和达到upperLimit*heapsize-->
<property>
<name>hbase.regionserver.global.memstore.upperLimit</name>
<value>0.6</value>
</property>
<!--点上所有region的memstore之和达到lowerLimit*heapsize默认为0.35-->
<property>
<name>hbase.regionserver.global.memstore.lowerLimit</name>
<value>0.55</value>
</property>
<property>
<name>hfile.block.cache.size</name>
<value>0.19</value>
</property>
<!--单个ColumnFamily的region大小,按照ConstantSizeRegionSplitPolicy策略,超过设置的该值则自动split,默认20G,重要!region的split是最伤的-->
<property>
<name>hbase.bucketcache.ioengine</name>
<value>offheap</value>
</property>
<property>
<name>hbase.bucketcache.size</name>
<value>39936</value>
</property>
<property>
<name>hbase.bucketcache.percentage.in.combinedcache</name>
<value>0.80</value>
</property>
<property>
<name>hbase.hregion.max.filesize</name>
<value>107374182400</value>
</property>
具体内存分配,可以参考这几篇文章,写的非常不错。
HBase BlockCache系列 – 走进BlockCache(http://hbasefly.com/2016/04/08/hbase-blockcache-1/)
HBase BlockCache系列 - 探求BlockCache实现机制(http://hbasefly.com/2016/04/26/hbase-blockcache-2/)
HBase最佳实践-内存规划(http://hbasefly.com/2016/06/18/hbase-practise-ram/)强烈推荐
HBase最佳实践-聊聊HBase核心配置参数(https://sq.163yun.com/blog/article/170965000956645376)