本文分析RegionServer宕机后这个region server上的region是如何在其他region server上恢复的。

region server宕机后发生了什么  

HMaster有一个RegionServerTracker对象,监控zk上/hbase/rs目录下的结点,达到监控region server下线的目的。一个region server宕机后,zk上相应结点删除,触发RegionServerTracker的nodeDeleted(),方法调用ServerManager的expireServer逻辑,对于非meta region(0.96后只有一个meta region),提交一个ServerShutdownHanlder的任务给内部线程池处理,任务的处理逻辑在handler的process()中。HBASE-7006引入了distributed log replay特性,这里以distributed log replay为例。如果开启了distributed log replay特性,那么在zk上建立一系列结点/hbase/recovering-regions/regionEncodeName/serverName,其中regionEncodeName结点内容为该region的last flush sequence id,即这个sequence id之前的所有数据都已经flush到磁盘上产生了HFile文件,这部分数据不需要进行回放。serverName结点的内容为宕机的region server上的last flushed sequence id,即所有region中最大的last flush sequence id。将宕掉server上的region assign通过round robin的方式assign其他的活着的region server,然后提交一个LogReplayHandler的任务给内部线程池,这个任务内部就是进行split log的准备工作,将hdfs上该region server的log改名,加上-splitting后缀,变成hbase.rootdir/WALs/serverName-splitting,然后进入HMaster的SplitLogManager管理范围,在zk上建立节点,路径/hbase/splitWAL/对上面改写后的log路径的encode。然后HMaster等待log被其他region server上的SplitLogWorker split完成,然后将一开始建立的一系列节点/hbase/recovering-regions/regionEncodeName/serverName删掉,然后将-splitting目录删除.

regionserver上的SplitLogWorker会不断的去监控zk上的hbase.rootdir/WALs/serverName-splitting节点,并且试图own这个节点.成功后,则给SplitLogWorker内部线程池提交一个HLogSplitterHandler任务,任务逻辑在对象splitTaskExecutor中,任务内部主要调用HLogSplitter.splitLogFile(),从而进到HLogSplitter的boolean splitLogFile(FileStatus logfile, CancelableProgressable reporter) throws IOException. 该函数内部会读-splitting目录内部的hlog文件,然后将每条log entry加入到一个sink中,sink是一个抽象类,根据是否配置使用distributed log replay,使用不同的子类,对于distributed log replay来说,使用LogReplayOutputSink,否则使用LogRecoveredEditsOutputSink。回到函数boolean splitLogFile(FileStatus logfile, CancelableProgressable reporter) throws IOException,函数的逻辑主要是从hlog中解析出一条条的log entry,如果log entry的sequence id比zk上相应的/hbase/recovering-regions/regionEncodeName 节点记录的sequence id小,那么说明这条log entry对应的内容已经持久化在HFile中,不需要进行回放,否则将这条日志append到成员EntryBuffers对象中,EntryBuffers内部会对log entry按照region进行分组,同一个Region的log entry记录在对象RegionEntryBuffer中。同时,会有一些写线程,不断的从EntryBuffers中取出RegionEntryBuffer对象,将其append到sink中,在这里,是LogReplayOutputSink。LogReplayOutputSink中积攒到一批日志,会调用WALEditsReplaySink的replayEntries()方法,通过ReplayServerCallable这个rpc发给这个region被assign后的新的region server让其回放,由于这里使用多个写线程给其他的region server发送日志,所以叫作distributed log replay。

非distributed log replay的模式下,LogRecoveredEditsOutputSink的工作是直接按照region,把相对应的log写到hdfs的 hbase.rootdir/data/namespace(比如test)/table_name/region_encoded_name/recovered.edits下。后续region被其他region server open时,会来这看是不是有需要回放的hlog.

需要注意的是,在distributed log replay模式下,region是被open后,然后才replay ,可以看到open成功后,这个region可以提供写,但是不能提供读,因为数据不全。

以上是region server宕机后,触发的HMaster和其他region server的逻辑。

下面看看region server 收到HMaster的open region指令的逻辑。

Open Region

如果是distributed log replay,那么会去zk上找 /hbase/recovering-regions/regionEncodeName/serverName,将region记录在map recoveringRegions中。然后如果不是meta region,则提交一个OpenRegionHandler任务到内部线程池中,任何的逻辑主要是open region,代码在openHRegion(final CancelableProgressable reporter),最后主要代码在initializeRegionInternals()内部调用initializeRegionStores()方法中。这个方法主要就是从hdfs中load region对应的HFile文件,并且如果region目录下的recovered.edits有hlog文件需要回放,则进行回放(方法replayRecoveredEditsIfAny)。

加载HFile过程中很重要的一点是,需要将这个HRegion下的所有的HStore(一个column family对应一个HStore,一个HStore下面有多个HFile和一个memstore)中最大的memstoreTS拿出来,加1后去初始化HRegion内部的mvcc对象,这个对象用于负责实现MVCC。这个时间戳相当于事物ID,用来判断数据是否对某事务可见。

参考资料

hbase-server-0.98.3-hadoop2.jar

https://issues.apache.org/jira/browse/HBASE-7006

http://blog.cloudera.com/blog/2012/07/hbase-log-splitting/

HBase RegionServer宕机处理恢复的更多相关文章

  1. HBase–RegionServer宕机恢复原理

    Region Server宕机总述 HBase一个很大的特色是扩展性极其友好,可以通过简单地加机器实现集群规模的线性扩展,而且机器的配置并不需要太好,通过大量廉价机器代替价格昂贵的高性能机器.但也正因 ...

  2. 如何避免regionServer宕机

    为什么regionserver 和Zookeeper的session expired? 可能的原因有 1. 网络不好. 2. Java full GC, 这会block所有的线程.如果时间比较长,也会 ...

  3. 支持宕机自动恢复触发一次性或周期性任务执行的组件包首次介绍-easyTask

    easyTask介绍 一个方便触发一次性或周期性任务执行的工具包,支持海量,高并发,高可用,宕机自动恢复任务 使用场景 需要精确到秒的某一时刻触发任务执行.比如订单交易完成24小时后如果客户未评价,则 ...

  4. 假如Kafka集群中一个broker宕机无法恢复,应该如何处理?

    假如Kafka集群中一个broker宕机无法恢复, 应该如何处理? 今天面试时遇到这个问题, 网上资料说添加新的broker, 是不会自动同步旧数据的. 笨办法 环境介绍 三个broker的集群, z ...

  5. hbase的regionserver宕机

    错误日志: regionserver.HRegionServer: Failed deleting my ephemeral node zookeeper.RecoverableZooKeeper: ...

  6. 整合phoenix4.6.0-HBase-1.0到cdh5..4.7 编译phoenix4.6源码 RegionServer 宕机

    Phoenix 集成HBase Phoenix 版本:phoenix-4.6.0-HBase-1.0 源码下载地址: http://apache.cs.uu.nl/phoenix/phoenix-4. ...

  7. 一次修改数据库物理文件造成Mysql宕机的恢复记录

    事件起始 某夜,我正在床上冥想准备入睡,忽然同事向我求救:消息内容如下: Oh My Gold 改了些配置,啥都没了!都没了!没了!了! 我仔细询问,原来是她因为某些原因将某库的物理文件夹改名后,发现 ...

  8. mysql group replication 主节点宕机恢复

    一.mysql group replication 生来就要面对两个问题: 一.主节点宕机如何恢复. 二.多数节点离线的情况下.余下节点如何继续承载业务. 在这里我们只讨论第一个问题.也就是说当主结点 ...

  9. HBase RegionServer Pause for hours 卡顿几小时 故障

    关键词:hbase jvm gc regionserver wal pause 背景: HBase 1.1.2 客户的hbase集群最近出现RegionServer宕机情况.跟踪了master和RS日 ...

随机推荐

  1. Spark编程环境搭建(基于Intellij IDEA的Ultimate版本)(包含Java和Scala版的WordCount)(博主强烈推荐)

    福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号:   大数据躺过的坑      Java从入门到架构师      人工智能躺过的坑         Java全栈大联盟   ...

  2. 极高效内存池实现 (cpu-cache)

    视频请看 : http://edu.csdn.net/course/detail/627 1.内存池的目的 提高程序的效率 减少运行时间 避免内存碎片 2.原理   要解决上述两个问题,最好的方法就是 ...

  3. ELK日志系统之通用应用程序日志接入方案

    前边有两篇ELK的文章分别介绍了MySQL慢日志收集和Nginx访问日志收集,那么各种不同类型应用程序的日志该如何方便的进行收集呢?且看本文我们是如何高效处理这个问题的 日志规范 规范的日志存放路径和 ...

  4. 开始使用Newbe.Pct-Web自动化测试

    前篇介绍了,使用 Newbe.Pct 之前的准备工作.本篇将开始介绍如何使用本项目运行第一个测试用例. 阅前语 从本篇开始,读者将会接触到使用一些代码.希望读者不必纠结于语法本身.出现代码的地方都会伴 ...

  5. NOI2018 退役记

    退役预订... upd 果然就这么不光荣的退役了... 我居然考出了一场只有两题得分的比赛,我好菜啊... 不过高三充(tui)实(fei)的生活应该很有意思... 大家一起加油吧!!!

  6. 触摸UITextView找到该触摸点的文字

    参加了一个比赛有一道题是如标题一样,在UITextView上触摸找到该触摸点对应的文字,比赛也可以查资料,当时做的时候就是抱着玩玩的心态试试也没认真做,就没查就去吃饭去了,昨晚下班回去在思考这个问题发 ...

  7. VM CentOS 问题汇总

    1. 锁定文件失败 / 模块启动失败 如下图问题: 原因分析: 虚拟机为了防止有多虚拟机共用一个虚拟磁盘(就是后 缀为.vmdk那个文件)造成数据的丢失等问题,每次启动虚拟机时会给每个虚拟磁盘加一个磁 ...

  8. springboot之约定大约配置

    前言 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样 ...

  9. Java中接口的特点

    Java接口在1.8之后发生了重大变化.所以谈Java接口特点可以分为1.8版本之前和1.8版本之后. 1.8版本之前的特点: 接口里只能有静态全局常量和public修饰的抽象方法. 为了代码简洁,在 ...

  10. Linux下socket通信和epoll

    上一篇博客用多线程实现服务端和多个客户端的通信,但是在实际应用中如果服务端有高并发的需求,多线程并不是一个好选择. 实现高并发的一种方法是IO多路复用,也就是select,poll,epoll等等. ...