文档章节

HBase region的split过程浅析

costaxu
 costaxu
发布于 2017/02/18 23:37
字数 1987
阅读 613
收藏 0

作为一个hbase的使用者来说并不会感知到region的存在。不过作为一个使用者,对于region这个词也不应该感到陌生,因为hbase在部署的时候有很多的region server。region是hbase实现上的一个存储单元。其实,我们所有的hbase数据都被存放在不同的region里。

从10000米的高空,我们可以这样理解region和hbase的架构:
1、Table在行的方向上分割为多个Region;
2、Region按大小分割的,每个表开始只有一个region,随着数据增多,region不断增大,当增大到一个阀值的时候,region就会等分会两个新的region,之后会有越来越多的region;
3、Region是Hbase中分布式存储和负载均衡的最小单元,不同Region分布到不同RegionServer上。

深入到region的内部,我们可以看到这样的region的解剖图。

region内部分成多个store。每个store负责管理和存储一个column family的数据。也就是说,一张表有多少个column family,一个region内部会生成多少个store与之对应。一个store里会有一个memstore和n个storefile。其中memstore是在regionserver的内存中。而storefile会保存持久化的保存在HDFS上。

region的设计让我想起了level db的设计。事实上region在实现过程中也在很大程度上参考了bit table的tablet的设计,也就是level db的设计。

memstore带来了两个好处:

1 所有的写入操作只写入wal日志文件和memstore中。wal日志文件是追加写, 而且磁盘的顺序IO速度很快, 因此写操作是极快完成的。

2 数据有了一个高速缓存。部分读请求可以直接命中缓存而省去了读磁盘之苦。

wal日志文件,hbase中的叫法是HLog,也是放在HDFS中。因为HDFS这一层的存在,使得一个数据库服务的high available的问题变得简单了。如果一个region server发生了故障,那么它所管理的memstore肯定就丢失了。但由于wal日志文件的存在,接管的region server可以轻易的将原来的region接管过来。它只需要找到wal日志文件中还没有落地成HFile的部分,重放请求并写入memstore就可以了。

如果数据不断的写入同一个region,会发生什么事?

首先随着数据的写入, memstore肯定是不够用了,需要flush到磁盘上形成Hfile。

随着HFile越来越多,可能触发compact过程。将多个HFile合并成一个HFile。

然后数据越来越多,HFile也越来越大。虽然HFile当中有索引,但索引的查询也是需要时间的。

另外大量的读写请求会汇聚到同一台region server上,服务器也会越来越繁忙。当达到它性能的极限后。。。天知道会发生些什么。

因此,当一个region过大之后,是需要进行split的。split的目的,是将一个region尽可能均匀的分成两个region。因为所有的HFile数据文件都是不可修改的, 所以新创建的子region不会重写数据到新文件中。在子region中,首先会使用的是父region的数据文件的reference。当子region逐渐通过compact,不再使用父region的数据文件的reference,就可以清理掉这些reference和父region的文件。

split的过程,由单个region的region server所发起。整个过程牵涉很多服务,zookeeper/master都会涉及到。region server需要在split开始前和结束后通知master, 更新meta表使client可以发现新的子region, 此外还需更新hdfs中的目录和文件。为了在错误发生时回滚, region server在内存中保存着split的执行journal。

 

当split发生时有这些步骤:

1 region server发起split。它会在zookeeper上创建一个节点,名称叫做/hbase/region-in-transition/region-name。状态为splitting。

2 因为master会监听/hbase/region-in-transition目录,所以它会得知split的发生。

3 region server在父region的hdfs目录下,创建一个叫做.splits的子目录。

4 region server在服务内部将父region关闭,并flush memstore。region在本地数据结构中的状态标记为offline也就是离线。此时,所有客户端访问父region的请求都会失败,并抛出NotServingRegionException异常。客户端会在等待一定时间后重试这个请求。

5 region server在.splits目录下创建子region的目录以及必要的数据结构。对于一个store file会创建两个reference file,并将reference file指向父region的文件。

6 region server创建真正的region目录,并移动这些reference文件。

7 region server 发送一个PUT请求到meta表,请求将父region在META中的状态设置成offline,并增加子region的信息。注意,此时并没有在meta表中增加子region的行,而只是修改父region的信息。在这时,客户端请求读、写父region的数据,都依然是返回出错。如果此时region server挂掉,那么接手它工作的region server依然能将split的工作做完。

8 region server同时打开两个子region接受请求。

9 region server将两个子region的加入到meta表中。此时,客户端会发现新的region,并可以向新的region发送请求。如果客户端本地有缓存meta表信息,缓存会失效。

10 region server将zookeeper上的/hbase/region-in-transition/region-name的状态改成split。master可以感知到split的完成。在迟些时候,balancer可以将子region分配到其他的region server。

11 split已经完成。但还有些垃圾需要清理。meta和hdfs中还保存着父region的reference。子region在compact之后会删除父region的reference。而master的垃圾回收任务,会定期检查region是否还在使用reference, 如果不再使用就会全部删除父region的数据文件。

在使用HBase的过程中,我曾经遇到过一个问题。在压力测试写一张hbase的表的过程中,出现了一张表一直不能结束split过程,而一直处在splitting的状态。而客户端也一直抛出NotServerRegionException异常。

查询了一下对应的region server的日志发现,一直打印这样的错误,非常频繁,一秒钟之内有几百上千次。

hbase-gdata-regionserver-tdmtest2.log

2017-02-18 15:16:53,542 WARN  [B.DefaultRpcServer.handler=29,queue=2,port=60020] regionserver.HRegion: Failed getting lock in batch put, row=3eb3b773-5fac-4638-86d1-930d68604ae3
org.apache.hadoop.hbase.regionserver.WrongRegionException: Requested row out of range for row lock on HRegion login_event_20170217,8024051d-360b-4877-a9b9-ebef10810e65,1487322174053.c9be23e25c28188f0af105e9a79593ec., startKey='8024051d-360b-4877-a9b9-ebef10810e65', getEndKey()='', row='3eb3b773-5fac-4638-86d1-930d68604ae3'
    at org.apache.hadoop.hbase.regionserver.HRegion.checkRow(HRegion.java:3636)
        at org.apache.hadoop.hbase.regionserver.HRegion.getRowLockInternal(HRegion.java:3667)
        at org.apache.hadoop.hbase.regionserver.HRegion.doMiniBatchMutation(HRegion.java:2430)
        at org.apache.hadoop.hbase.regionserver.HRegion.batchMutate(HRegion.java:2297)
        at org.apache.hadoop.hbase.regionserver.HRegion.batchMutate(HRegion.java:2252)
        at org.apache.hadoop.hbase.regionserver.HRegion.batchMutate(HRegion.java:2256)
        at org.apache.hadoop.hbase.regionserver.HRegionServer.doBatchOp(HRegionServer.java:4538)
        at org.apache.hadoop.hbase.regionserver.HRegionServer.doNonAtomicRegionMutation(HRegionServer.java:3718)
        at org.apache.hadoop.hbase.regionserver.HRegionServer.multi(HRegionServer.java:3607)
        at org.apache.hadoop.hbase.protobuf.generated.ClientProtos$ClientService$2.callBlockingMethod(ClientProtos.java:30954)
        at org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:2093)
        at org.apache.hadoop.hbase.ipc.CallRunner.run(CallRunner.java:101)
        at org.apache.hadoop.hbase.ipc.RpcExecutor.consumerLoop(RpcExecutor.java:130)
        at org.apache.hadoop.hbase.ipc.RpcExecutor$1.run(RpcExecutor.java:107)
        at java.lang.Thread.run(Thread.java:745)

通过仔细分析上面的步骤可以发现,这个region server的错误发生在第四步之后和第八步之前。因为客户端还没找到新的region,而且在对应的meta表里也没有发现新的region。因此我采取了重启对应region server的方式进行处理。因为此时如果错误发生在第7步之前,接手的region server不知道split的发生,依然可以正常处理请求。而错误发生在第7步之后,region server会完成split的过程。

重启region server的过程需要注意,千万不能使用 stop-hbase.sh进行关闭,因为这样会关闭整个集群。

而需要在对应的region server上用 bin/graceful_stop.sh regionservername的方式进行关闭。使用bin/hbase-daemon.sh start regionserver。启动之后,故障排除,region split完成。集群恢复了服务。

 

 

© 著作权归作者所有

costaxu

costaxu

粉丝 145
博文 56
码字总数 86451
作品 0
深圳
程序员
私信 提问
HBase运维基础——元数据逆向修复原理

背景 鉴于上次一篇文章——“云HBase小组成功抢救某公司自建HBase集群,挽救30+T数据”的读者反馈,对HBase的逆向工程比较感兴趣,并咨询如何使用相应工具进行运维等等。总的来说,就是想更深...

Mr_zebra
2018/05/02
67
0
Hive查询HBase调用MapReduce性能优化

折腾了很久,被领导天天督促&指点,算是有个最基本的性能优化。 1. 背景介绍: Hive使用hive-hbase-handler建立HBase external table。在hive查询包含count(*)、join、以及Predicate Pushdow...

orisonchan
2018/08/09
0
0
大数据Spark优化读取Hbase--region 提高并行数过程详细解析

一. Hbase 的 region 我们先简单介绍下 Hbase 的 架构和 region : 从物理集群的角度看,Hbase 集群中,由一个 Hmaster 管理多个 HRegionServer,其中每个 HRegionServer 都对应一台物理机器...

金铭鼎IT教育
2018/12/17
53
0
HBase集群出现NotServingRegionException问题的排查及解决方法

HBase集群出现NotServingRegionException问题的排查及解决方法 Posted by 原 攀峰 on 2012 年 11 月 25 日 Leave a commentGo to comments HBase集群在读写过程中,可能由于Region Split或R...

vieky
2013/01/04
191
0
HBase运维基础――元数据逆向修复原理

  【IT168 评论】   背景   鉴于上次一篇文章――“云HBase小组成功抢救某公司自建HBase集群,挽救30+T数据”的读者反馈,对HBase的逆向工程比较感兴趣,并咨询如何使用相应工具进行运...

云栖社区
2018/05/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

详解RPC远程调用和消息队列MQ的区别

什么是RPC RPC(Remote Procedure Call)远程过程调用,主要解决远程通信间的问题,不需要了解底层网络的通信机制。 RPC服务框架有哪些 知名度较高的有Thrift(FB的)、dubbo(阿里的) RPC的一般...

一只会编程的狼
30分钟前
5
0
Dubbo面试题

支持的调用方式 同步调用 异步调用 参数回调 事件通知 支持的注册中心 Dubbo线上支持三种注册中心:自带的Simple Registry、Redis和Zookeeper,当然,最常用的还是Zookeeper作为注册中心,因...

i不歪
37分钟前
5
0
idea打包jar发布到nexus

8.idea打包jar发布到nexus 1. 配置maven的nexus地址 打开maven配置文件:\apache-maven-X.X.X\conf\settings.xml 修改配置为: <localRepository>E:\maven</localRepository> <pluginGroup......

TopDuang
39分钟前
6
0
nvm 使用方式

nvm 使用方式 命令: nvm ls-remote:列出所有可以安装node 版本号 nvm install v10.4.0:安装指定版本号的node nvm use v10.3.0:切换node版本,这个是全局的 nvm current:当前nod...

潇潇程序缘
39分钟前
4
0
八爪鱼爬网页分页数据

一个yuanbeth
43分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部