代码改变世界

Hadoop之RPC通信

2014-08-09 17:17  hduhans  阅读(316)  评论(0)    收藏  举报

  RPC(remote procedure call protocol),远程过程调用协议,是hadoop框架运行的基础。这里的远程并不是指距离上的远,而是指不同java进程间的对象方法的调用。调用的发生在服务端执行,客户端只获取结果。

  服务端提供的对象必须是一个接口,并且extends VersionedProtocol。客户端能够调用的方法必须位于接口池中。

 

一、动手测试Hadoop之RPC运行实例(完整项目测试源码点此下载):

1、新建Java项目,添加如下jar包:hadoop-core-1.1.2.jar、commons-logging-1.1.1.jar、commons-lang-2.4.jar、commons-configuration-1.6.jar。

2、新建接口文件IMyJob,继承VersionedProtocol。

package hdfs;

import org.apache.hadoop.ipc.VersionedProtocol;

public interface IMyJob extends VersionedProtocol {

    public static final long Version = 1316L;

    public abstract String hello(String name);

}
View Code

3、新建服务端被调用的对象类MyJob,继承IMyJob并实现相关方法。

package hdfs;

import java.io.IOException;

public class MyJob implements IMyJob {

    /* (non-Javadoc)
     * @see hdfs.IMyJob#hello(java.lang.String)
     */
    public String hello(String name) {
        System.out.println("我被调用了");
        return "hello " + name;
    }

    @Override
    public long getProtocolVersion(String arg0, long arg1) throws IOException {
        return Version;
    }

}
View Code

4、新建服务类MyServer,开启对象MyJob的服务并监听。

package hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.ipc.RPC.Server;

public class MyServer {

    public static final String SERVER_ADDRESS = "localhost";
    public static final int SERVER_PORT = 6789;

    public static void main(String[] args) throws Exception {

        Server server = RPC.getServer(new MyJob(), SERVER_ADDRESS, SERVER_PORT, new Configuration());
        server.start();
        
    }
}
View Code

5、新建客户端MyClient,连接服务器并获取执行方法的结果。

package hdfs;

import java.net.InetSocketAddress;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;

public class MyClient {

    public static void main(String[] args) throws Exception {
        
        IMyJob proxy = (IMyJob)RPC.waitForProxy(IMyJob.class, IMyJob.Version, new InetSocketAddress(MyServer.SERVER_ADDRESS, MyServer.SERVER_PORT), new Configuration());
        
        String res = proxy.hello("hans");
        System.out.println("remote function called result:"+res);
        
        RPC.stopProxy(proxy);
    }
}
View Code

6、常见错误信息:

   1)提示:java.lang.NoClassDefFoundError: org/apache/commons/configuration/Configuration

      解决:添加commons-logging、commons-lang、commons-configuration、commons-collections四个jar包

 

二、DataNode与NameNode通过RPC机制通信过程

  RPC远程过程调用协议是Hadoop的通信基础,是整个框架运行的基础。Hadoop定义了用于实现DataNode与NameNode通信的接口。NameNode并不会主动与发起与DataNode的通信,唯一的通信方式是在DataNode代理调用NameNode的方法的返回值中包含相应的消息

图2.1 DataNode与NameNode之RPC通信机制示意图

   HDFS操作类FileSystem的内部有一个DFSClient对象,在DFSClient中定义了一个ClientProtocol的对象namenode,namenode初始化并获取NameNode类的RPC代理,当我们操作FileSystem类时,namenode对象就与远程调用主节点上的NameNode进程通信,这就是FileSystem与NameNode的RPC通信过程。

 

三、HDFS之RPC通信说明
1、通信接口:

  1) ClientDatanodeProtocol :一个客户端和datanode之间的协议接口,用于数据块恢复;

  2) ClientProtocol :client与Namenode交互的接口,所有控制流的请求均在这里,如:创建文件、删除文件等;

  3) DatanodeProtocol :Datanode与Namenode交互的接口,如心跳、blockreport等;

  4) NamenodeProtocol :SecondaryNode与Namenode交互的接口。

2、通信示意图,如下图所示。

图3.2.1 HDFS之RPC通信协议


四、MapReduce之RPC通信说明

  通信接口:

  1) InterTrackerProtocol :TaskTracker与JobTracker交互的接口,功能与DatanodeProtocol相似;

  2) JobSubmissionProtocol :JobClient与JobTracker交互的接口,用来提交Job、获得Job等与Job相关的操作;

  3) InterDatanodeProtocol :Datanode内部交互的接口,用来更新block的元数据;

  4) TaskUmbilicalProtocol :Task中子进程与母进程交互的接口,子进程即map、reduce等操作,母进程即TaskTracker,该接口可以回报子进程的运行状态(词汇扫盲: umbilical 脐带的, 关系亲密的)