`
yunsamzhang
  • 浏览: 70056 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

hadoop的心跳回忆

阅读更多
hadoop的集群是基于master/slave模式,namenode和jobtracker属于master,而datanode/tasktracker属于slaves。master只有一个,而slaves有多个。

namenode与datanode之间的通信,jobtracker与tasktracker直接的通信,都是通过“心跳”完成的。

以前看过hadoop心跳原理的源代码,今天再回忆一下,呵呵,所以叫“心跳回忆”。


1、心跳机制

心跳的机制大概是这样的:
1) master启动的时候,会开一个ipc server在那里。
2) slave启动时,会连接master,并每隔3秒钟主动向master发送一个“心跳”,将自己的状态信息告诉master,然后master也是通过这个心跳的返回值,向slave节点传达指令。


2、找到心跳的代码

拿namenode和datanode来说,在datanode的offerService方法中,每隔3秒向namenode发送心跳的代码:

 /**
   * Main loop for the DataNode.  Runs until shutdown,
   * forever calling remote NameNode functions.
   */
  public void offerService() throws Exception {
     
    ...

    //
    // Now loop for a long time....
    //

    while (shouldRun) {
      try {
        long startTime = now();

        //
        // Every so often, send heartbeat or block-report
        //
        
	// 如果到了3秒钟,就向namenode发心跳
        if (startTime - lastHeartbeat > heartBeatInterval) {
          //
          // All heartbeat messages include following info:
          // -- Datanode name
          // -- data transfer port
          // -- Total capacity
          // -- Bytes remaining
          //
          lastHeartbeat = startTime;
          DatanodeCommand[] cmds = namenode.sendHeartbeat(dnRegistration,
                                                       data.getCapacity(),
                                                       data.getDfsUsed(),
                                                       data.getRemaining(),
                                                       xmitsInProgress.get(),
                                                       getXceiverCount());

	  // 注意上面这行代码,“发送心跳”竟然就是调用namenode的一个方法??

          myMetrics.heartbeats.inc(now() - startTime);
          //LOG.info("Just sent heartbeat, with name " + localName);

	  // 处理对心跳的返回值(namenode传给datanode的指令)
          if (!processCommand(cmds))
            continue;
        }

  	// 这里省略很多代码
	...
    } // while (shouldRun)
  } // offerService

上面这段代码,如果是单机的程序,没什么值得奇怪的。但是,这是hadoop集群!datanode和namenode在2台不同的机器(或2个JVM)上运行!datanode机器竟然直接调用namenode的方法!这是怎么实现的?难道是传说中的RMI吗??

下面我们主要就来分析这个方法调用的细节。


3、心跳的底层细节一:datanode怎么获得namenode对象的?

首先,DataNode类中,有一个namenode的成员变量:
public class DataNode extends Configured 
    implements InterDatanodeProtocol, ClientDatanodeProtocol, FSConstants, Runnable {
  ...
  public DatanodeProtocol namenode = null;
  ... 
}

下面是NameNode类的定义:
public class NameNode implements ClientProtocol, DatanodeProtocol,
                                 NamenodeProtocol, FSConstants,
                                 RefreshAuthorizationPolicyProtocol {
  ... 
}


注意:NameNode实现了DatanodeProtocol接口,DatanodeProtocol接口定义了namenode和datanode之间通信的方法。

那么,DataNode类是怎么获取到NameNode类的引用呢?

在Datanode端,为namenode变量赋值的代码:
    // connect to name node
    this.namenode = (DatanodeProtocol) 
      RPC.waitForProxy(DatanodeProtocol.class,
                       DatanodeProtocol.versionID,
                       nameNodeAddr, 
                       conf);


在继续去RPC类中追踪:
VersionedProtocol proxy =
        (VersionedProtocol) Proxy.newProxyInstance(
            protocol.getClassLoader(), new Class[] { protocol },
            new Invoker(addr, ticket, conf, factory));


现在,明白了!
1) 对namenode的赋值,并不是真正的new了一个实现了DatanodeProtocol接口的对象,而是获得了一个动态代理!!
2) 上面这段代码中,protocol的类型是DatanodeProtocol.class
3) 对namenode的所有调用,都被委托(delegate)给了Invoker


4、心跳的底层细节二:看看Invoker类

Invoker类是org.apache.hadoop.ipc.RPC类的一个静态内部类:

	 private static class Invoker implements InvocationHandler {
在这个类中,看invoke方法:
  
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			...

		      ObjectWritable value = (ObjectWritable)
		        client.call(new Invocation(method, args), address, 
		                    method.getDeclaringClass(), ticket);
      			...
		      return value.get();
		   }

所有的方法调用又被delegate给client的call方法了!

client是Invoker中的成员变量:
  
 private Client client;

所以可以看出:DatanodeProtocol中的每个方法调用,都被包装成一个Invocation对象,再由client.call()调用


5、心跳的底层细节三:Invocation类

Invocation类是org.apache.hadoop.ipc.RPC类的一个静态内部类

没有什么业务逻辑方法,主要作用就是一个VO


6、心跳的底层细节四:client类的call方法

接下来重点看client类的call方法:
  public Writable call(Writable param, InetSocketAddress addr, 
                       Class<?> protocol, UserGroupInformation ticket)  
                       throws InterruptedException, IOException {

    Call call = new Call(param);   
		// 将Invocation转化为Call
    Connection connection = getConnection(addr, protocol, ticket, call);
		// 连接远程服务器
    connection.sendParam(call);                 // send the parameter
		// 将“序列化”后的call发给过去
    boolean interrupted = false;
    synchronized (call) {
      while (!call.done) {
        try {
          call.wait();                           // wait for the result
		// 等待调用结果
        } catch (InterruptedException ie) {
          // save the fact that we were interrupted
          interrupted = true;
        }
      }

      if (interrupted) {
        // set the interrupt flag now that we are done waiting
        Thread.currentThread().interrupt();
      }

      if (call.error != null) {
        if (call.error instanceof RemoteException) {
          call.error.fillInStackTrace();
          throw call.error;
        } else { // local exception
          throw wrapException(addr, call.error);
        }
      } else {
        return call.value;
		// 返回
      }
    }
  }



7、现在,一目了然了

datanode向namenode发送heartbeat过程是这样的:

	a) 在datanode初始化获得namenode的proxy
	b) 在datanode上,调用namenode proxy的heartbeat方法:
		namenode.sendHeartbeat(dnRegistration,
                                                       data.getCapacity(),
                                                       data.getDfsUsed(),
                                                       data.getRemaining(),
                                                       xmitsInProgress.get(),
                                                       getXceiverCount());
	c) 在datanode上的namenode动态代理类将这个调用包装成(或者叫“序列化成”)一个Invocation对象,并调用client.call方法
	d) client call方法将Invocation转化为Call对象
	e) client 将call发送到真正的namenode服务器
	f) namenode接收后,转化成namenode端的Call,并process后,通过Responder发回来!
	g) datanode接收结果,并将结果转化为DatanodeCommand[]
		



8、再看动态代理

动态代理:让“只有接口,没事对应的实现类”成为可能,因为具体方法的实现可以委托给另一个类!!

在这个例子中,就datanode而言,DatanodeProtocol接口是没有实现类的!


*** THE END ***

分享到:
评论
3 楼 mygirl1987 2010-10-27  
那datanode发送心跳也是走的50010端口吗?我不想让datanode发送心跳给namenode,就是杀死datanode某个节点,该禁掉它哪个端口呀?
2 楼 tedeyang 2010-07-12  
写得很好。
接口模式的远程RPC基本都是如此实现的,譬如hessian。
1 楼 niumd 2010-07-12  
楼主在做东西,采用hadoop;介绍hadoop的文章一直很少

相关推荐

    hadoop winutils hadoop.dll

    Hadoop是Apache软件基金会开发的一个开源分布式计算框架,它允许在普通硬件上高效处理大量数据。在Windows环境下,Hadoop的使用与Linux有所不同,因为它的设计最初是针对Linux操作系统的。"winutils"和"hadoop.dll...

    hadoop2.7.3 Winutils.exe hadoop.dll

    在IT行业中,Hadoop是一个广泛使用的开源框架,主要用于大数据处理和分布式存储。Hadoop 2.7.3是这个框架的一个稳定版本,它包含了多个改进和优化,以提高性能和稳定性。在这个版本中,Winutils.exe和hadoop.dll是两...

    hadoop的dll文件 hadoop.zip

    Hadoop是一个开源的分布式计算框架,由Apache基金会开发,它主要设计用于处理和存储大量数据。在提供的信息中,我们关注的是"Hadoop的dll文件",这是一个动态链接库(DLL)文件,通常在Windows操作系统中使用,用于...

    hadoop.dll & winutils.exe For hadoop-2.7.1

    在大数据处理领域,Hadoop是一个不可或缺的开源框架,它提供了分布式存储和计算的能力。本文将详细探讨与"Hadoop.dll"和"winutils.exe"相关的知识点,以及它们在Hadoop-2.7.1版本中的作用。 Hadoop.dll是Hadoop在...

    hadoop2.7.3的hadoop.dll和winutils.exe

    在IT行业中,Hadoop是一个广泛使用的开源框架,主要用于大数据处理和分布式存储。Hadoop 2.7.3是Hadoop发展中的一个重要版本,它包含了众多的优化和改进,旨在提高性能、稳定性和易用性。在这个版本中,`hadoop.dll`...

    hadoop的hadoop.dll和winutils.exe下载

    在Hadoop生态系统中,`hadoop.dll`和`winutils.exe`是两个关键组件,尤其对于Windows用户来说,它们在本地开发和运行Hadoop相关应用时必不可少。`hadoop.dll`是一个动态链接库文件,主要用于在Windows环境中提供...

    hadoop2.7.7对应的hadoop.dll,winutils.exe

    在Hadoop生态系统中,Hadoop 2.7.7是一个重要的版本,它为大数据处理提供了稳定性和性能优化。Hadoop通常被用作Linux环境下的分布式计算框架,但有时开发者或学习者在Windows环境下也需要进行Hadoop相关的开发和测试...

    win环境 hadoop 3.1.1安装包

    Hadoop是一个由Apache软件基金会开发的开源框架,它允许使用简单的编程模型在分布式环境中存储和处理大数据。它主要由四个核心组件构成:Hadoop Common、HDFS(Hadoop Distributed File System)、YARN(Yet Another...

    Hadoop下载 hadoop-2.9.2.tar.gz

    Hadoop 是一个处理、存储和分析海量的分布式、非结构化数据的开源框架。最初由 Yahoo 的工程师 Doug Cutting 和 Mike Cafarella Hadoop 是一个处理、存储和分析海量的分布式、非结构化数据的开源框架。最初由 Yahoo...

    Hadoop下载 hadoop-3.3.3.tar.gz

    Hadoop是一个由Apache基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进 Hadoop是一个由Apache基金会所开发的分布式系统基础架构。用户可以在不...

    hadoop2.7.3 hadoop.dll

    在windows环境下开发hadoop时,需要配置HADOOP_HOME环境变量,变量值D:\hadoop-common-2.7.3-bin-master,并在Path追加%HADOOP_HOME%\bin,有可能出现如下错误: org.apache.hadoop.io.nativeio.NativeIO$Windows....

    hadoop.dll & winutils.exe For hadoop-2.6.0

    在Hadoop生态系统中,`hadoop.dll`和`winutils.exe`是两个关键组件,尤其对于Windows用户来说。本文将详细介绍这两个文件以及它们在Hadoop 2.6.0版本中的作用。 `hadoop.dll`是Hadoop在Windows环境下运行所必需的一...

    win环境 hadoop 3.1.0安装包

    在Windows环境下安装Hadoop 3.1.0是学习和使用大数据处理技术的重要步骤。Hadoop是一个开源框架,主要用于分布式存储和处理大规模数据集。在这个过程中,我们将详细讲解Hadoop 3.1.0在Windows上的安装过程以及相关...

    hadoop2.6 hadoop.dll+winutils.exe

    标题 "hadoop2.6 hadoop.dll+winutils.exe" 提到的是Hadoop 2.6版本中的两个关键组件:`hadoop.dll` 和 `winutils.exe`,这两个组件对于在Windows环境中配置和运行Hadoop至关重要。Hadoop原本是为Linux环境设计的,...

    hadoop-2.7.0.tar

    Hadoop-2.7.0.tar是一个著名的开源分布式存储与计算系统Hadoop的安装包。Hadoop是由Apache软件基金会开发的一个分布式系统基础架构,主要解决大数据问题。Hadoop的设计初衷是可靠、高效、可伸缩地存储和处理大数据集...

    windows下的hadoop-3.1.4

    在Windows环境下安装和使用Hadoop可能对于一些初学者来说,是件挑战性较大的任务。不过,随着技术社区的不断发展,越来越多的教程和文章出现,为人们提供了宝贵的指导和帮助。本篇文档将详细介绍如何在Windows操作...

    hadoop2.7.4 hadoop.dll包括winutils.exe

    Hadoop是Apache软件基金会开发的一个开源分布式计算框架,主要由HDFS(Hadoop Distributed File System)和MapReduce两大部分组成,旨在提供一种可靠、可扩展、高效的数据处理和存储解决方案。在标题中提到的...

    winutils+hadoop.dll+eclipse插件(hadoop2.7)

    在Hadoop生态系统中,`winutils.exe`和`hadoop.dll`是Windows环境下运行Hadoop必备的组件,尤其对于开发和测试环境来说至关重要。这里我们深入探讨这两个组件以及与Eclipse插件的相关性。 首先,`winutils.exe`是...

    Hadoop3.1.3.rar

    Hadoop是Apache软件基金会开发的一个开源分布式计算框架,它的核心设计是处理和存储大量数据的能力。这个名为"Hadoop3.1.3.rar"的压缩包文件包含了Hadoop 3.1.3版本的所有组件和相关文件,使得用户可以下载并进行...

    hadoop2.6.0插件+64位winutils+hadoop.dll

    在IT行业中,Hadoop是一个广泛使用的开源框架,主要用于大数据处理和分布式存储。Hadoop2.6.0是这个框架的一个重要版本,它包含了多项优化和改进,以提高系统的稳定性和性能。在这个压缩包中,我们关注的是与Windows...

Global site tag (gtag.js) - Google Analytics