HBase中JVM基本配置
在JVM中,默认情况下会设置minimum heap size 为 1/64 可用物理内存,并为maximum heap size设置 1/4 的物理可用内存(不过在Java8 之前,默认最大是1g)。当然,我们可以通过手动指定 JVM 参数,配置JVM的内存,例如:
-Xms10g -Xmx10g
在HBase 中,也可以在 hbase-env.sh 中显示指定堆内存大小,例如:
# The maximum amount of heap to use. Default is left to JVM default.
# export HBASE_HEAPSIZE=1G
这里有个问题是:是否要同时设置-Xms 与 -Xmx为一相同的值?若是将他们设置为同一一个固定值,则它们的优缺点有:
对于一些垃圾回收的算法,例如G1,将它们锁定为同一值会更好
不设置 -Xms可以让VM启动更快,但是接下来,需要在每轮gc 增长堆内存后,才会达到一个稳定状态。这样会导致在启动后,最开始会带来一些延迟,这个延时并不是我们在HBase中期望看到的,因为HBase提供的服务一般都是交互式服务
若是设置-Xms与-Xmx为同一值,则JVM在启动时会稍慢,不过在正常启动后,不会再有隐含的内存大小调整的情况,所以会更稳定。而在RegionServer 的进程中,我们可以在分配工作给它前,稍等一会而,以缓解启动进程的消耗。
对于HMaster进程,一般不需要太大内存,2GB 到 4GB就可以满足master的工作需求,因为它的对象分配与销毁的频率远小于RegionServer。
对于RegionServer 进程,若是物理机内存为64GB,则一开始可以给它分配10GB的-Xmx,之后可以根据监控(如jstat等)再进行向上调整。不过若是分配了较大的堆内存,我们也必须要考虑不同的GC算法,以支持更大堆内存中的垃圾回收。
基于以上场景,我们可以在hbase-env.sh 中配置以下参数:
# Set environment variables here.
export HBASE_MASTER_OPTS="-Xms2g -Xmx2g"
export HBASE_REGIONSERVER_OPTS="-Xms10g -Xmx10g"
如前文所述,不指定-Xms的话,堆内存需要在增长多次后才能到达最大堆内存,导致在重新分配内存时的不必要开销,所以最好是按上述指定。
HBase中的堆内存管理
在RegionServer中,主要的任务为:接收并处理读写请求。不过除此之外,RegionServer也需要在内存中维护一些内部信息,例如:对于每个打开的region来说,它们都需要在内存里结构化存储,以处理一些常规操作。
在RegionServer启动后,所分配的JVM堆内存大小就已经指定了,无法再增加。所以对于这部分已有的内存,我们需要谨慎使用,其中最重要的一部分就是:如何调整可供读写操作使用的可用内存。
在HBase 1.0 之前,主要有两个参数需要调整,分别为memstores(对于写)以及block cache(对于读)。剩下的内存被用于所有其他杂项使用(例如Java用于存储打开的region的结构)。对于memstore,我们有以下两个参数可以指定:
hbase.regionserver.global.memstore.upperLimit:默认为0.4(40%),也就是memstore可以使用的最大堆内存
hbase.regionserver.g