Hadoop RPC整个使用流程——以DataNode向NameNode注册为例

Hadoop RPC整个使用流程——以DataNode向NameNode注册为例 node

在HDFS实现过程当中DataNode class中有一个成员变量namenode,其类型是DatanodeProtocol。namenode能够看做是远程NameNode服务器的一个代理,由于NameNode自己也是DatanodeProtocol接口的具体实现;DataNode经过调用namenode对象的方法与远程NameNode进行交互。 服务器

下面看一下namenode变量在DataNode当中是如何初始化的: socket

首先DataNode经过调用RPC.waiForProxy方法完成namenode的初始化过程,具体实现看下面的代码: oop

this.namenode = (DatanodeProtocol) RPC.waitForProxy( this

DatanodeProtocol.class,   DatanodeProtocol.versionID, debug

    nameNodeAddr,  代理

            conf); orm

经过上面的代码能够看出,具体namenode是如何与远程的NameNode进行链接的须要经过查阅RPC.waitForProxy(...)来查看。waitForProxy经过RPC内部的一系列方法调用,最终经过下面的getProxy方法来实现: server

public static VersionedProtocol getProxy( 对象

Class<? extends VersionedProtocol> protocol, 

long clientVersion,

InetSocketAddress addr, 

UserGroupInformation ticket,

Configuration conf, 

SocketFactory factory,

int rpcTimeout)throws IOException {

if (UserGroupInformation.isSecurityEnabled()) {

SaslRpcServer.init(conf);

}

VersionedProtocol proxy = (VersionedProtocol)                       Proxy.newProxyInstance(

protocol.getClassLoader(), 

new Class[] { protocol },

new Invoker(protocol, addr, ticket, conf, factory,                      rpcTimeout));

long serverVersion =                                             proxy.getProtocolVersion(protocol.getName(),

clientVersion);

if (serverVersion == clientVersion) {

return proxy;

} else 

        {

throw new VersionMismatch(protocol.getName(),                   clientVersion,

serverVersion);

}

}

上面标注为红色的代码是proxy获取的关键(目前对Java Proxy的具体做用不是很了解。可是据猜想做用应该是这样的,Proxy产生了一个protocol的一个具体对象,可是对该对象全部方法的调用都是经过Invoker中的invoke方法来进行调用,也就是其最终的方法调用是经过Invoker的invoke方法进行实现的),其中Invoker是该方法的关键,咱们看一下Invoker的具体实现:

Invoker是InvocationHandler接口的具体实现(Invoker implements InvocationHandler),其中必须实现的方法是:

public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {

final boolean logDebug = LOG.isDebugEnabled();

long startTime = 0;

if (logDebug) {

startTime = System.currentTimeMillis();

}

ObjectWritable value = (ObjectWritable) client.call(new Invocation(

method, args), remoteId);

if (logDebug) {

long callTime = System.currentTimeMillis() - startTime;

LOG.debug("Call: " + method.getName() + " " + callTime);

}

return value.get();

}

invoke方法经过调用client.call方法完成与远程服务器的调用,client是RPC Client的一个实例。RPC Client具体完成与远程服务器经过socket进行交互的功能。

相关文章
相关标签/搜索