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進行交互的功能。

相關文章
相關標籤/搜索