HBase region server作为一个Java程序,启动时应该指定max heap size,比方说8G。那这8G会被如何使用呢?
1. 作为每个region的mem store,缺省是64M。那么如果这个region server一共有100个region的话,就要用掉64M*100=6.4G内存了。
2. 作为block cache用,缺省是20%的内存用作block cache,那么就是8G*20% = 1.6G。
3. 其他对象分配。
从上面的情况可以看到,如果这个region server只有8G的heap size的话,在100个region的情况下,内存已经完全用完了(6.4G+1.6G),这样的话,就非常容易出OutOfMemoryError了。当然在实际使用中,基本不会因为这个原因产生OOME。这主要是因为HBase的这个配置hbase.regionserver.global.memstore.upperLimit(缺省是40%的内存)起了作用。但这是有代价的。其代价就是block住所有在这个region server上的update操作并强制进行flush以释放内存。这样的话,整个region server在这段时间内就不响应任何请求。所以,应该限制每个HBase region server的region个数。按照Google的经验,这个数字应该不超过100。
读HBase的source code可以发现,对于put heavy的应用来说,mem store flush只发生在mem store满的情况。而由flush又进一步引起minor compaction, major compaction和split。所以为了减少flush次数,似乎应该增大mem store size并相应减少region个数。这样应该会对写入速度有好处。回头实验下吧。