Region Splitting
步骤
- RegionServer开始split region,SPLIT事务开启。RegionServer在表上获取共享读锁防止split过程中数据被修改。接着在zk中创建一个znode,标记为SPLITTING。
- Master 将会观察到该znode的创建。
- RegionServer在父region的目录下创建一个名为.splits的子目录。
- RegionServer关闭父region,并将其下线。此时客户端请求该rs上的此region将会抛出NotServingRegionException,并回退重试。
- RegionServer在.splits目录下为子region创建region目录,同时在子region的目录中创建引用文件,指向父region下的文件。
- RegionServer创建子region的实际存储目录,并将引用文件移动到该目录下。
- RegionServer向.META表发送put请求。将.META表中父region的状态设置为下线,同时在表中添加子region的信息。此时子region不会在.META表中有单独的条目信息。如果请求成功,父region的split将是有效的。如果在rpc成功之前失败,master和之后打开该region的RegionServer将会清除split留下的脏数据。
- RegionServer并行打开所有的子region。
- RegionServer将子region的信息添加到.META,此时split region是online状态了。之后客户端就可以发现并向新的region请求。客户端默认会缓存.META在本地,每次请求RegionServer或.META时也会更新缓存。
- RegionServer将zk中的znode的后缀改为split,以便master能够观察到该事件。如果有需要balancer可以自由的重新分配子region到其他的regionserver。此时整个split事务结束。
- split完成后,.META和HDFS会仍然包含对父region的引用。当子region发生compaction并将文件重写后,该引用会被清除。master会周期的运行gc tasks来检查子region是否仍然在引用父region的文件。
Region状态
棕色:下线状态,一种特殊状态,如瞬时状态(closed之后、opening之前)、terminal(表的region被禁用)、初始状态(表的region刚被创建)
淡绿色:在线状态,region可以接受请求
浅蓝色:瞬时状态、短暂或临时状态
红色:失败状态,需要注意
金色:region拆分/合并的终端状态
灰色:通过拆分/合并创建的region的初始状态
- OFFLINE:region下线,未打开
- OPENING:region正在打开中
- OPEN:region已经打开,并且RegionServer已通知master
- FAILED_OPEN:RegionServer打开region失败
- CLOSING:region正在关闭中
- CLOSED:region已经被关闭,并且RegionServer已通知master
- FAILED_CLOSE:RegionServer关闭region失败
- SPLITTING::region正在spliting,RegionServer已通知master
- SPLIT:region已经完成spliting,RegionServer已通知master
- SPLITTING_NEW:通过split产生的region正在被创建
- MERGING:region正在与另一个region合并,RegionServer已通知master
- MERGED:region已经合并完成,RegionServer已通知master
- MERGING_NEW:两个region合并产生的新region正在被创建
过程
- master将region从OFFLINE变为OPENING状态,并尝试分配该region到RegionServer。master会发起RPC请求,RegionServer收到后开始打开region
- 如果RegionServer未收到请求,master将会重试,直到rs收到请求或超过重试次数。如果master的重试次数用完,则即使RegionServer开始打开该region,master也会通过将该region变为到CLOSING状态并尝试关闭该region来阻止RegionServer打开该region。
- RegionServer打开region之后,会通知master。等待master将region变为OPEN状态,之后通知RegionServer,region已经打开。
- 如果RegionServer不能打开region,同样会通知master。此时master会将region置为CLOSED状态,并尝试在其他的RegionServer上打开region
- 如果region在多个rs在均无法open,master会将region置为FAILED_OPEN状态。
- master将region从OPEN置为CLOSING状态,并通知RegionServer
- 如果RegionServer不在线,将会抛出NotServingRegionException,master会将region置为OFFLINE状态,并重新分配到其他RegionServer
- 如果RegionServer在线,但不可达。master会将region置为FAILED_CLOSE状态
- 如果RegionServer收到关闭region的请求,它将关闭region并通知master。master会将region置为CLOSED状态,并重新分配到其他RegionServer
- 在分配region之前,如果region处于CLOSED状态,master会将region置为OFFINE状态
- 当RegionServer开始split region,会通知master。master会将该region从OPEN置为SPLITING状态,同时增加两个新创建的region(处于SPLITING_NEW状态)到RegionServer。
- 通知master之后,RegionServer将开始split region。RegionServer将会通知master更新hbase:meta表。如果split成功,则region将会从SPLITING置为SPLIT状态,两个新region将从SPLITING_NEW状态置为OPEN状态
- 如果split失败,则正在split的region将会从SPLITING置为OPEN状态,两个新region将从SPLITING_NEW状态置为OFFLINE状态
- RegionServer通知master准备开始合并两个region。master会将两个region从OPEN置为MERGING状态,同时增加一个新创建的region(处于MERGING_NEW状态)到RegionServer。
- 通知master之后,RegionServer开始合并两个region。RegionServer将会通知master更新hbase:meta表。如果merge成功,则两个region将会从MERGING置为MERGED状态,新合并的region将从MERGING_NEW状态置为OPEN状态
- 如果合并失败,则两个region将会从MERGING置为OPEN状态,新合并的region将从MERGING_NEW状态置为OFFLINE状态
- 对于处于FAILED_OPEN或FAILED_CLOSED状态的region,当通过hbase shell进行重分配操作时,master将会尝试再次关闭region。