文档章节

hadoop 2.4 namenode ha 源码分析(ActiveStandbyElector)

东方神剑
 东方神剑
发布于 2014/11/04 19:06
字数 1081
阅读 625
收藏 0
点赞 0
评论 0

在hadoop nn的HA,对于主备节点的选举,是通过ActiveStandbyElector来实现的。源码上有针对该类的解释。


小弟英文不才,翻译一下。该类主要使用了zookeeper实现了主节点的选举,对于成功选举的主节点,会在zookeeper上创建零时节点。如果创建成功,NN会变成active,而其余nn节点会成备用节点。

下面还是来具体分析一下ActiveStandbyElector类的作用,ActiveStandbyElector主要实现了选举,选举流程主要是通过创建零时节点的方式实现,如果创建成功。可以认为是获取到对应的LOCK,该节点可以成为active。如果没有成功创建该节点,可以认为为standby节点,对于standby节点,需要一直监听该LOCK节点的状态。如果发生节点的事件,就去尝试选举。基本流程就是这样。

下面,来看一下ActiveStandbyElector类的主要方法和流程。对于熟悉zookeeper的同学来说,zookeeper的必须要实现watcher接口,其中可以实现自己的各种事件的处理逻辑。

在ActiveStandbyElector中,采用了

内部类来实现Watcher接口,其process方法,调用了processWatchEvent来实现具体的业务处理。


下面来分析该processWatchEvent的具体逻辑:

 //处理zk的事件

 synchronized     void     processWatchEvent(ZooKeeper zk, WatchedEvent event) {     Event.EventType eventType = event.getType(); 
    if     (isStaleClient(zk)) return; 
    LOG.debug("Watcher event type: "     + eventType + " with state:" 
        + event.getState() + " for path:"     + event.getPath() 
        + " connectionState: "     + zkConnectionState 
        + " for "     + this); 
  
    if     (eventType == Event.EventType.None) { 
        //会话本身的时间,如连接。失去连接。           // the connection state has changed           switch     (event.getState()) { 
      case     SyncConnected: 
        LOG.info("Session connected."); 
        // if the listener was asked to move to safe state then it needs to             // be undone             ConnectionState prevConnectionState = zkConnectionState; 
        zkConnectionState = ConnectionState.CONNECTED; 
        if     (prevConnectionState == ConnectionState.DISCONNECTED && 
            wantToBeInElection) { 
          monitorActiveStatus();//监控节点             } 
        break; 
      case     Disconnected: 
        LOG.info("Session disconnected. Entering neutral mode..."); 
  
        // ask the app to move to safe state because zookeeper connection             // is not active and we dont know our state             zkConnectionState = ConnectionState.DISCONNECTED; 
        enterNeutralMode(); 
        break; 
      case     Expired: 
        // the connection got terminated because of session timeout             // call listener to reconnect             LOG.info("Session expired. Entering neutral mode and rejoining..."); 
        enterNeutralMode(); 
        reJoinElection(0);//参与选举             break; 
      case     SaslAuthenticated: 
        LOG.info("Successfully authenticated to ZooKeeper using SASL."); 
        break; 
      default: 
        fatalError("Unexpected Zookeeper watch event state: " 
            + event.getState()); 
        break; 
      } 
  
      return; 
    } 
      
    // a watch on lock path in zookeeper has fired. so something has changed on         // the lock. ideally we should check that the path is the same as the lock         // path but trusting zookeeper for now         //节点事件         String path = event.getPath(); 
    if     (path != null) { 
      switch     (eventType) { 
      case     NodeDeleted: 
        if     (state == State.ACTIVE) { 
          enterNeutralMode();//该方法目前未实现             } 
        joinElectionInternal();//开始选举             break; 
      case     NodeDataChanged: 
        monitorActiveStatus();//继续监控该节点,尝试成为active             break; 
      default: 
        LOG.debug("Unexpected node event: "     + eventType + " for path: "     + path); 
        monitorActiveStatus(); 
      } 
  
      return; 
    } 
  
    // some unexpected error has occurred         fatalError("Unexpected watch error from Zookeeper"); 
  }

 


而joinElectionInternal,选举的核心方法就是,

选举就是通过对zkLokFilePath节点的创建,来完成。这个采用了zk的异步回调。

从该类的定义,可以看出,本身就是实现了zk的两个接口。

StatCallback需要实现的方法,如下:


对于两个方法的实现,ActiveStandbyElector内部实现几乎是一样的。这里不再贴上源码,有兴趣的可以自己去看源码。

贴上实现方法,有注释。呵呵

 public     synchronized     void     processResult(int     rc, String path, Object ctx, 
      String name) { 
    if     (isStaleClient(ctx)) return; 
    LOG.debug("CreateNode result: "     + rc + " for path: "     + path 
        + " connectionState: "     + zkConnectionState + 
        "  for "     + this); 
  
    Code code = Code.get(rc);//为了方便使用,这里自定义了一组状态         if     (isSuccess(code)) {//成功返回,成功创建zklocakpath节点           // we successfully created the znode. we are the leader. start monitoring           if     (becomeActive()) {//要将本节点上的NN变成active             monitorActiveStatus();//继续监控节点状态           } else     { 
        reJoinElectionAfterFailureToBecomeActive();//失败,继续选举尝试           } 
      return; 
    } 
  
    if     (isNodeExists(code)) {//节点存在,说明已经有active,wait即可           if     (createRetryCount == 0) { 
        // znode exists and we did not retry the operation. so a different             // instance has created it. become standby and monitor lock.             becomeStandby(); 
      } 
      // if we had retried then the znode could have been created by our first           // attempt to the server (that we lost) and this node exists response is           // for the second attempt. verify this case via ephemeral node owner. this           // will happen on the callback for monitoring the lock.           monitorActiveStatus();//不过努力成为active的动作不能停           return; 
    } 
  
    String errorMessage = "Received create error from Zookeeper. code:" 
        + code.toString() + " for path "     + path; 
    LOG.debug(errorMessage); 
  
    if     (shouldRetry(code)) { 
      if     (createRetryCount < maxRetryNum) { 
        LOG.debug("Retrying createNode createRetryCount: "     + createRetryCount); 
        ++createRetryCount; 
        createLockNodeAsync(); 
        return; 
      } 
      errorMessage = errorMessage 
          + ". Not retrying further znode create connection errors."; 
    } else     if     (isSessionExpired(code)) { 
      // This isn't fatal - the client Watcher will re-join the election           LOG.warn("Lock acquisition failed because session was lost"); 
      return; 
    } 
  
    fatalError(errorMessage); 
  }


对于becomeStandby,becomeActive这些状态的改变,有ZKFailoverController来实现。这里只做调用,不做实现。下面会分析ZKFailoverController是如何协调完成一些了的选举,状态监控,重新选举等过程。

© 著作权归作者所有

共有 人打赏支持
东方神剑

东方神剑

粉丝 63
博文 126
码字总数 93166
作品 0
朝阳
程序员
Hadoop 2.0中单点故障解决方案总结

项目构建 Hadoop 1.0内核主要由两个分支组成:MapReduce和HDFS,众所周知,这两个系统的设计缺陷是单点故障,即MR的JobTracker和HDFS的NameNode两个核心服务均存在单点问题,该问题在很长时间...

jackwxh ⋅ 2017/03/15 ⋅ 0

hadoop2.2.0集群的HA高可靠的最简单配置

hadoop中的NameNode好比是人的心脏,非常重要,绝对不可以停止工作。在hadoop1时代,只有一个NameNode。如果该NameNode数据丢失或者不能工作,那么整个集群就不能恢复了。这是hadoop1中的单点...

蓝狐乐队 ⋅ 2014/04/28 ⋅ 0

hadoop全分布式高可用方案

集群规划: 主机名 IP 安装的软件 运行的进程 hadoop01 192.168.88.155 jdk、hadoop、zookeeper DataNode、NodeManager、JournalNode、QuorumPeerMain hadoop02(A)192.168.88.164 jdk、hadoo......

泡海椒 ⋅ 2015/12/20 ⋅ 0

Hadoop手把手逐级搭建,从单机伪分布到高可用+联邦(4)Hadoop高可用+联邦(HA+Federation)

第四阶段: Hadoop高可用+联邦(HA+Federation) 0. 步骤概述 1. 为高可用保存hadoop配置 1.1 进入$HADOOP_HOME/etc/目录 1.2 备份hadoop高可用配置,供以后使用 1.3 查看$HADOOP_HOME/etc/目录...

bigablecat ⋅ 01/05 ⋅ 0

Hadoop手把手逐级搭建,从单机伪分布到高可用+联邦(3)Hadoop高可用(HA)

第三阶段: Hadoop高可用(HA) 0. 步骤概述 1. 为完全分布式保存hadoop配置 1.1 进入$HADOOP_HOME/etc/目录 1.2 备份hadoop完全分布式配置,命名为hadoop-full,供以后使用 1.3 查看$HADOOP_HOM...

bigablecat ⋅ 01/03 ⋅ 0

hadoop2.x的配置一

hadoop该怎么配置配置文件? 1.找到官网的配置文件,用官网的配置文件做参考,进官网找对应版本的document,找到Configuration,下面就有相应配置文件了。 2.官网的配置文件只是做参考,配置...

cjun1990 ⋅ 2015/08/05 ⋅ 0

Setting Up Hadoop NameNode High Availability

Hadoop2.0以后,2个NameNode的数据其实是实时共享的。新HDFS采用了一种共享机制,Quorum Journal Node(JournalNode)集群或者Nnetwork File System(NFS)进行共享。NFS是操作系统层面的,J...

candon123 ⋅ 01/03 ⋅ 0

国内最全最详细的hadoop2.2.0集群的HA高可靠的最简单配置

简介 hadoop中的NameNode好比是人的心脏,非常重要,绝对不可以停止工作。在hadoop1时代,只有一个NameNode。如果该NameNode数据丢失或者不能工作,那么整个集群就不能恢复了。这是hadoop1中...

吴超沉思录 ⋅ 2014/01/26 ⋅ 3

hadoop2配置文件详细解释

文章地址:http://www.superwu.cn/2014/02/12/1094/ 前言 hadoop是分布式系统,运行在linux之上,配置起来相对复杂。对于hadoop1,很多同学就因为不能搭建正确的运行环境,导致学习兴趣锐减。...

闵开慧 ⋅ 2014/04/03 ⋅ 0

Hadoop2.6.1集群部署之手工切换HA

1. 引言 在生产环境中NameNode的高可用是非常重要的,一旦NameNode宕机,那么整合集群就不能用了,在本篇博客中就主要介绍一下Hadoop2.6.1的HA部署(手动切换),在本篇博客中博主使用五台干...

Liri ⋅ 2017/12/16 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Java Web如何操作Cookie的添加修改和删除

创建Cookie对象 Cookie cookie = new Cookie("id", "1"); 修改Cookie值 cookie.setValue("2"); 设置Cookie有效期和删除Cookie cookie.setMaxAge(24*60*60); // Cookie有效时间 co......

二营长意大利炮 ⋅ 今天 ⋅ 0

【每天一个JQuery特效】淡入淡出显示或隐藏窗口

我是JQuery新手爱好者,有时间就练练代码,防止手生,争取每天一个JQuery练习,在这个博客记录下学习的笔记。 本特效主要采用fadeIn()和fadeOut()方法显示淡入淡出的显示效果显示或隐藏元...

Rhymo-Wu ⋅ 今天 ⋅ 0

Spring JDBC使用方法

普通实现: 1、创建数据表customer。 可以使用任何数据库实现,在项目中要引入相应数据库驱动包并配置相应数据库连接。 2、创建Customer pojo。 Customer类的属性对应数据库的属性,除了为每...

霍淇滨 ⋅ 今天 ⋅ 0

Contos 7 安装Jenkins

Jenkins是一款能提高效率的软件,它能帮你把软件开发过程形成工作流,典型的工作流包括以下几个步骤 开发 提交 编译 测试 发布 有了Jenkins的帮助,在这5步中,除了第1步,后续的4步都是自动...

欧虞山 ⋅ 今天 ⋅ 0

revel

revel install go get github.com/revel/revelgo get github.com/revel/cmd create new app revel new git.oschina.net/zdglf/myapp run app revel run git.oschina.net/zdglf/myapp ot......

zdglf ⋅ 今天 ⋅ 0

49. Group Anagrams - LeetCode

Question 49. Group Anagrams Solution 思路:维护一个map,key是输入数组中的字符串(根据字符排好序) Java实现: public List<List<String>> groupAnagrams(String[] strs) { Map<Strin......

yysue ⋅ 今天 ⋅ 0

spring Email

使用spring发Email其实就是使用spring自己封装携带的一个javamail.JavaMailSenderImpl类而已。这个类可以当一个普通的java对象来使用,也可以通过把它配置变成spring Bean的方式然后注入使用...

BobwithB ⋅ 今天 ⋅ 0

spark 整理的一些知识

Spark 知识点 请描述spark RDD原理与特征? RDD全称是resilient distributed dataset(具有弹性的分布式数据集)。一个RDD仅仅是一个分布式的元素集合。在Spark中,所有工作都表示为创建新的...

tuoleisi77 ⋅ 今天 ⋅ 0

思考

时间一天天过感觉自己有在成长吗?最怕的是时光匆匆而过,自己没有收获!下面总结下最近自己的思考。 认识自己 认识另一个自己,人们常说要虚心听取别人意见和建议。然而人往往是很难做到的,...

hello_hp ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部