如何解决region太小和region太大带来的后果
问题分析
考官主要考核你是否具有HBase的使用经验,以及对region的理解和优化配置。
核心问题讲解
Region概念
Region是HBase中表数据分布和访问的基本单位, HBase中的表是根据row key的值水平分割成所谓的region的。集群中负责管理Region的结点叫做Region server。Region server负责数据的读写。每一个Region server大约可以管理1000个region。
regionServer 其实是hbase的服务,部署在一台物理服务器上,region有一点像关系型数据的分区,数据存放在region中,当然region下面还有很多结构,确切来说数据存放在memstore和hfile中。我们访问hbase的时候,先去hbase 系统表查找定位这条记录属于哪个region,然后定位到这个region属于哪个服务器,然后就到哪个服务器里面查找对应region中的数据。
Region数量
通常较少的region数量可使群集运行的更加平稳,官方指出每个RegionServer大约100个regions的时候效果最好,理由如下:
HBase的一个特性MSLAB,它有助于防止堆内存的碎片化,减轻垃圾回收Full GC的问题,默认是开启的。但是每个MemStore(写缓存)需要2MB。所以如果每个region有2个列簇(一个列簇对应一个写缓存memstore),总有1000个region,就算不存储数据也要3.95G内存空间。
如果很多region,它们中Memstore也过多,内存大小触发Region Server级别限制导致flush动作,就会对用户请求产生较大的影响,可能阻塞该Region Server上的更新操作。
HMaster要花大量的时间来分配和移动Region,且过多Region会增加ZooKeeper的负担。
从HBase读入数据进行处理的mapreduce程序,Map数量默认由涉及的region数量决定,过多Region会产生太多Map任务数量。
所以,如果一个HRegion中Memstore过多,而且大部分都频繁写入数据,每次flush的开销必然会很大,因此我们也建议在进行表设计的时候尽量减少ColumnFamily的个数。每个region都有自己的MemStore,当大小达到了上限(hbase.hregion.memstore.flush.size,默认128MB),会触发Memstore刷新。
合理分配region的数量,根据写请求量的情况,一般20-200个之间,可以提高集群稳定性,排除很多不确定的因素,提升读写性能。
Region大小
HBase中数据一开始会写入memstore,满128MB(看配置)以后,会flush到disk上而成为storefile(region包含多个storefile)。当storefile数量超过触发因子时,会启动compaction压缩过程将它们合并为一个storefile,对集群的性能有一定影响。而当合并后的storefile大小大于max.filesize,会触发分割动作,将它切分成两个region。
- 当region比较小时(hbase.hregion.max.filesize),触发split的机率更大,系统的整体访问服务会出现不稳定现象。
- 当region比较大时,由于长期得不到split,因此同一个region内storefile数量过多,发生多次compaction压缩的机会增加了。这样会降低系统的性能、稳定性,因此平均吞吐量会受到一些影响而下降。
region不宜过大或过小,经过实战,生产高并发运行下,最佳大小5-10GB!
问题扩展
RegionServer结构
当RegionServer(RS)收到写请求的时候(writerequest),RS会将请求转至相应的Region。Region下包含了多个Memstore(写缓存)和StoreFile, StoreFile又包含了多个Hfile。Memstore位于RS的主内存中,而HFiles被写入到HDFS中。当RS处理写请求的时候,数据首先写入到Memstore,然后当到达一定的阀值的时候,Memstore中的数据会被刷到HFile中。
结合项目中使用
region数量设置在100个左右, 20-200个之间;region最佳大小5-10GB。