HBase检测宕机是通过Zookeeper实现的, 正常情况下RegionServer会周期性向Zookeeper发送心跳,一旦发生宕机,心跳就会停止,超过一定时间(SessionTimeout,我们集群配置的是30s)Zookeeper就会认为RegionServer宕机离线,并将该消息通知给Master。
Master检测到宕机之后会将宕机RegionServer上的所有Region重新分配到集群中其他正常RegionServer上去,再根据HLog进行丢失数据恢复,恢复完成之后就可以对外提供服务,整个过程都是自动完成的。
HBase切分HLog当前主要有两种模式Distributed Log Splitting和Distributed Log Replay。
由于我们的集群没有配置hbase.master.distributed.log.replay=true,所以这里主要研究Distributed Log Splitting流程。
Distributed Log Splitting
整体流程:
Master作为HLog切分任务的协调者,主要工作流程如下:
-
Master会将待切分日志路径发布到Zookeeper节点上(/hbase/splitWAL),每个日志作为一个任务,每个任务都会有对应状态,起始状态为TASK_UNASSIGNED
-
所有RegionServer启动之后都注册在这个节点上等待新任务,一旦Master发布任务之后,RegionServer就会抢占该任务
-
抢占任务实际上首先去查看任务状态,如果是TASK_UNASSIGNED状态,说明当前没有人占有,此时就去修改该节点状态为TASK_OWNED。如果修改失败,说明其他RegionServer也在抢占,修改成功表明任务抢占成功。
-
RegionServer抢占任务成功之后会分发给相应线程处理,如果处理成功,会将该任务对应zk节点状态修改为TASK_DONE,一旦失败会修改为TASK_ERR
-
Master会一直监听在该ZK节点上,一旦发生状态修改就会得到通知。任务状态变更为TASK_ERR的话,Master会重新发布该任务,而变更为TASK_DONE的话,Master会将对应的节点删除
Regionserver作为实际工作的执行者,抢占任务以及抢占任务之后的工作流程:
-
假设Master当前发布了3个任务,即当前需要回放3个日志文件,分别为hlog1、hlog2和hlog3
-
RegionServer1抢占到了hlog1和hlog2日志,RegionServer2抢占到了hlog3日志,
-
以RegionServer1为例,其抢占到hlog1和hlog2日志之后会分别分发给两个HLogSplitter线程进行处理,HLogSplitter负责对日志文件执行具体的切分,切分思路还是首先读出日志中每一个<HLogKey, WALEdit>数据对,根据HLogKey所属Region写入不同的Region Buffer,写入Region Buffer之前会对Entrys进行过滤,通过比较sequenceId,如果发现该Entry已经flush了,就跳过这个Entry。
-
每个Region Buffer都会有一个对应的写线程,将buffer中的日志数据写入hdfs中,写入路径为hdfs:/hbase/data/ns/table/region1/seqenceidN.temp,其中seqenceid是一个日志中某个region对应的最大sequenceid
-
针对某一region回放日志只需要将该region对应的所有文件按照sequenceid由小到大依次进行回放即可
源码:
-
检测宕机 发布任务:
-
RS抢占、处理任务
-
Region replay、上线
整个切分过程中可能出现的问题、解决方法:(持续更新)
1.RS节点假死后,DataNode进程处于存在但不可服务的状态,会导致hbase split wal超时到几乎无法进行,10分钟后DataNode彻底下线才能恢复性能
处理:联系SA关机、重启机器,可以加速集群恢复
- RS 切分任务失败时,Master会重新发布任务,如果某个切分任务卡死,无法顺利完成时,可以手动删除zookeeper上/hbase/splitWAL 下的任务节点,master会重新发布 (待验证)
参考:http://hbasefly.com/2016/10/29/hbase-regionserver-recovering/
网友评论