文档章节

hadoop 2.4 namenode ha 源码分析(ActiveStandbyElector)

_hadooper
 _hadooper
发布于 2014/10/30 22:37
字数 1081
阅读 4335
收藏 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是如何协调完成一些了的选举,状态监控,重新选举等过程。

© 著作权归作者所有

共有 人打赏支持
_hadooper
粉丝 11
博文 14
码字总数 10349
作品 0
南京
技术主管
Hadoop 2.0中单点故障解决方案总结

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

jackwxh
06/29
0
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
561
0
hadoop2.2.0集群的HA高可靠的最简单配置

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

蓝狐乐队
2014/04/28
0
0
NameNode HA的实现原理

NameNode HA架构概述 实现架构: 组件描述: Active NN和Standby NN:两台 NameNode 形成互备,一台处于 Active 状态,另外一台处于 Standby 状态,只有主 NameNode 才能对外提供读写服务。 ...

JPblog
2017/12/26
0
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
0

没有更多内容

加载失败,请刷新页面

加载更多

自定义Ubuntu/Windows双系统引导菜单主题

学习Linux自然少不了要装双系统,其中Ubuntu便是我们用的最多的Linux系统。装完双系统后,Ubuntu会自动生成grub开机引导及菜单,及其丑陋,而且很多我们用不到的选项。今天我们就介绍burg:修...

Linux就该这么学
29分钟前
1
0
Go 并发(二)

Go Mutex 通过Mutex和信道处理竞态条件。 临界区 当程序并发运行时,多个协程不应该同时访问那些修改共享资源的代码,这些修改共享资源的代码称为临界区。 Go中通过Mutex可以避免同时访问临界...

春哥大魔王的博客
32分钟前
2
0
CentOS 7安装和部署Docker

Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker 。通过 uname -r 命令查看你当前的内核版本 uname -r3.10.0-514.el7.x86_64 1、...

狼王黄师傅
35分钟前
1
0
php扩展可以通过pecl 或者phpize 安装

pecl 算是 php 扩展的一个官方聚合平台,一些比较有名,有特点的扩展会被 pecl 收录,收录后可以通过 pecl 的方式安装。但是更多的扩展是没有收录在 pecl 上的,这些扩展还是需要通过 phpize...

bengozhong
36分钟前
1
0
CentOS中如何安装7ZIP

执行以下命令下载安装: wget http://nchc.dl.sourceforge.net/project/p7zip/p7zip/9.20.1/p7zip_9.20.1_src_all.tar.bz2tar -jxvf p7zip_9.20.1_src_all.tar.bz2cd p7zip_9.20.1make......

凯文加内特
42分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部