HBase官方文档 之 Region的相关知识

HBase是以Region为最小的存储和负载单元(这里可不是HDFS的存储单元),所以Region的负载管理,关系到了数据读写的性能。先抛开Region如何切分不说,看看Region是如何分配到各个RegionServer的吧。html

更多内容参考——个人大数据学习之路node

Region在HBase中的角色

Table                    (HBase表)
    Region               (Region)
        Store            (每一个Region的每一个列族独立存储)
            MemStore     (MemStore每一个Store有一个,用于在内存中保存数据)
            StoreFile    (StoreFiles对应于Store,是具体存储在磁盘的文件)
                Block    (Blocks是HDFS上的存储单元)

Region的管理

通常来讲对于每一个Region Server,官方推荐最好是控制Region的数量在20-200个、大小在5-20Gb左右。算法

为何要控制region的数量呢?shell

  1. 默认MemStore须要2MB的空间用来存储数据,若是一台机器上有1000个Region,每一个有两个列族,那就须要3.9GB的数据。
  2. 若是同时以某个相同的频率更新全部的Region,当同时进行数据持久化的时候也会有问题
  3. Master对于维护大量的Region有很大的性能问题,由于在平衡Region的时候,在ZK中的操做都是同步的。
  4. Region Server须要维护Region的索引信息

那么Region Server是如何管理Region的呢?apache

启动

  1. Master建立AssignmentManager
  2. AssignmentManager查看当前的Region分配信息
  3. 知足条件后,经过LoadBalancerFactory建立LoadBalancer,1.0后的版本默认是StochasticLoadBalancer
  4. 判断是否须要进行负载平衡,并更新相关信息

容错

  1. 若是平衡负载的时候报错,RegionServer会直接关闭
  2. Master检测到resgion Server异常
  3. 重启Region server
  4. 请求进行重试;超时会请求其余的节点

Region的状态机

Hbase中每一个Region本身维护其在hbase:meta表中的信息。
异步

状态机中包括下面几种状态:oop

  • offline:region离线没有开启
  • opening:region正在被打开
  • open:region正在打开,而且region server通知了master
  • failed_open:regionserver打开失败
  • closing:region正在被关闭
  • closed:regionserver正在关闭,而且已经通知了master
  • failed_close:regionserver关闭失败了
  • splitting:region server通知master,region正在被切分
  • split:region server通知master,region已经被切分完了
  • spliting_new:region是切分过程当中新建的文件
  • merging:regionserver通知master region正在合并
  • merged:regionserver通知master region合并完了
  • merging_new:region是合并新建出来的

不一样的颜色是不一样含义:性能

  • 棕色:离线状态,属于一种短暂的瞬间状态(好比关闭后开启的中间状态)、中止状态或者初始化的时候的状态
  • 绿色:正常的状态,能够支持请求访问
  • 蓝色:短暂的状态
  • 红色:失败
  • 黄色:合并或者切分的状态
  • 灰色:刚开始的状态

各个序号表明不一样的操做场景:学习

  1. Master向region server发起region从offline到openning的状态请求,regionserver若是没有收到,master会尝试重试几回。RegionServer接收到请求后,regin状态变成opening
  2. 若是Master发起的open请求超过次数,那么不管region server是否已经打开region,master都会命令region server关闭文件,状态变为closing
  3. 当region server打开region后,会尝试通知master,让他把region状态修改成open,并通知regsion server。这样region才能变为open状态
  4. 若是region server打开四百,会尝试通知master。master会把region的状态变动为closed,而且尝试去其余的region server打开region
  5. 若是master尝试几回后,都没有打开region,就会把状态变动为failed_open
  6. master通知region server关闭region,若是没有反应,会重试
  7. 若是region server没有在线,会抛出异常。而后region的状态会变成closing
  8. 若是region server在线,可是好几回都没响应,就会更新状态为failed_close
  9. 若是region server收到请求,而且关闭了region,那么会通知master把region状态修改成closed。而且把region分配给其余的server
  10. 在分配以前,master会先把region从closed状态转换为offline
  11. 若是region server正在切分region,会通知mastere。master把region状态由open变为splitting,而且把新增两个region的信息,这两个region都是splitting_new状态
  12. 若是region切分红功,当前的region状态从splitting变成split;新增的两个region状态从splitting_new变成open
  13. 若是切分失败,状态从splitting回到open,两个region也从splitting_new变成offline
  14. 若是region server想要合并两个region,那么也会先通知master。master把两个region从open变成merging,而后增长一个新的region,状态为merging_new
  15. 若是合并成功, 旧的region从merging变为merged,新的region从merging_new变为open
  16. 若是合并失败,region的状态从merging变回open,新建的一个region状态又变成offline
  17. 若是管理员经过hbase shell操做分配region,master会尝试把失败的状态变成close

Region的数据本地性

数据本地性经过来自于hdfs client和hdfs block存储的节点差别性,针对数据备份来讲,会按照下面的机制进行:大数据

  1. 第一个备份会优先卸载本地node节点上
  2. 第二个备份会随机选择一个不一样的机架
  3. 第三个备份会在第二个备份所在的机架上,再随机选择一个节点
  4. 若是还有其余的备份节点,就在集群中随机选择了。

这样Hbase在刷新或者压缩时,能够体现数据的本地性。若是一个region server出现故障,那么就没有数据本地性可言了,由于它的备份都在其余的节点上。

Region的切分

HBase会配置一个切分的阈值,当到达阈值后,就会执行region的切分。Master不会参与Region的切分,切分由Region Server独立完成。执行切分的时候,会先把region下线,而后在meta表中增长子region的信息,最后通知给master。

默认使用的切分策略是IncreasingToUpperBoundRegionSplitPolicy(1.2.0版本),经过修改配置能够切换切分规则:

<property>
 <name>hbase.regionserver.region.split.policy</name>
 <value>org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy</value>
</property>

也能够经过Admin API指定规则:

HTableDescriptor tableDesc = new HTableDescriptor("test");
tableDesc.setValue(HTableDescriptor.SPLIT_POLICY, ConstantSizeRegionSplitPolicy.class.getName());
tableDesc.addFamily(new HColumnDescriptor(Bytes.toBytes("cf1")));
admin.createTable(tableDesc);

或者经过HBase shell管理:

hbase> create 'test', {METHOD => 'table_att', CONFIG => {'SPLIT_POLICY' => 'org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy'}},
{NAME => 'cf1'}

也能够经过HBaseConfiguration来配置:

HTableDescriptor myHtd = ...;
myHtd.setValue(HTableDescriptor.SPLIT_POLICY, MyCustomSplitPolicy.class.getName());

Region的手动切分

Region的切分能够在表建立的时候来执行,也可已在后期来作。最好是在设计表结构的时候,就把切分的规则考虑进去。由于:

  • 若是你的数据rowkey是随着时间自增加的,那么全部的新数据都会写在最后一个Region中,这样会致使老是最后一个region是热点,而其余的全部region基本都闲置了。
  • 有的时候是一些意外的状况致使的热点问题,好比table中存储的是每一个网页对应的点击日志,若是一个网页很受欢迎,那么它对应的region将会成为热点。
  • 当集群的region不少的时候,想要加快加载数据的速度
  • 在批量导入的时候,可能会形成region热点写

设计切分点

默认HBase都是基于Rowkey的字符进行切分的。若是rowkey是经过数字开头,那么会按照数字的范围进行切分;若是是字母,则会经过它的ASCII码进行切分。用户也能够自定义切分的算法,好比HexStringSplit经过转换成十六进制进行切分。

Region的合并

Master和RegionServer都会参与Region的合并。通常是Client发送合并的请求到Master,而后Master把须要合并的region移动到须要移动比例最高的那个Regsion Server上。好比如今有ABC3个Region Server,A有2个Region,B和C都只有一个,那么会把Region都转移到A Server,再执行合并操做。跟切分的过程同样,也须要先将region设置离线,而后执行合并,再去更新meta表信息。

下面是Hbase shell中合并的例子:

$ hbase> merge_region 'ENCODED_REGIONNAME', 'ENCODED_REGIONNAME'
$ hbase> merge_region 'ENCODED_REGIONNAME', 'ENCODED_REGIONNAME', true

合并操做是异步操做,发送请求后,客户端这边不须要登到合并结束。

第三个参数,表示是否强制合并。由于默认合并操做只能针对相邻的region,force参数能够强制跨Region的合并。

相关文章
相关标签/搜索