HDFS Namenode接收RPC请求过程
来源:互联网 发布:淘宝服务热线 人工 编辑:程序博客网 时间:2024/06/08 03:13
HDFS中所有控制消息通过RPC发送(数据消息直接使用Socket),所以让我们看看它的Under the hood.
org.apache.hadoop.ipc.RPC: RPC服务的建立调用等,其中内部类Server继承了org.apache.hadoop.ipc.Server.
org.apache.hadoop.ipc.ProtobufRpcEngine和WritableRpcEngine分别是RPCEngine的protobuf和writable实现,继承了org.apache.hadoop.ipc.RPC.Server.
具体看下listener,listener有多个Reader线程,每个Reader执行doRunLoop()主循环,遍历SelectionKeys,把可读的进行doRead(key):
doRead继续调用readAndProcess(),在读取完整个包(报头、Auth信息及其初始化、正文)之后调用processOneRpc(buf), 再调processData(buf)进行反序列化。
在processData(buf)中,通过Rpc报头获得一个Writable的实例:
在Handler中主循环取出Call以后有:
总结下,我们了解了一个RPC请求从java的TCP层到NamenodeRpcServer的调用过程,因为要做转发请求的工作,请求的回复以及请求的发起方式都是接下来要继续了解的内容。
对于Namenode,它的main函数位于org.apache.hadoop.hdfs.server.namenode.Namenode,而元数据的实际管理主要由FSNamesystem类完成,Namenode类则负责与外界的IPC通信以及一些配置工作。
Namenode有个NameNodeRpcServer的成员,专门负责处理RPC请求。在NameNodeRpcServer类中又有两个RPC.Server的成员变量,serviceRpcServer和clientRpcServer,分别接收来自Datanode和Client的请求。
源码中和RPC相关的类主要有几个:
org.apache.hadoop.ipc.Server:RPC服务在java.net和java.nio上的实现,封装了几个内部类如Call, Listener, Responder, Connection, Handler,具体见后文。org.apache.hadoop.ipc.RPC: RPC服务的建立调用等,其中内部类Server继承了org.apache.hadoop.ipc.Server.
org.apache.hadoop.ipc.ProtobufRpcEngine和WritableRpcEngine分别是RPCEngine的protobuf和writable实现,继承了org.apache.hadoop.ipc.RPC.Server.
追踪一下clientRpcServer服务器的启动、运行过程:
public synchronized void start() { responder.start(); listener.start(); handlers = new Handler[handlerCount]; for (int i = 0; i < handlerCount; i++) { handlers[i] = new Handler(i); handlers[i].start(); } }这里显然是responder回复RPC消息,listener接收RPC消息,handler负责处理消息。
具体看下listener,listener有多个Reader线程,每个Reader执行doRunLoop()主循环,遍历SelectionKeys,把可读的进行doRead(key):
Iterator<SelectionKey> iter = readSelector.selectedKeys().iterator(); while (iter.hasNext()) { key = iter.next(); iter.remove(); if (key.isValid()) { if (key.isReadable()) { doRead(key); } } key = null; }
doRead继续调用readAndProcess(),在读取完整个包(报头、Auth信息及其初始化、正文)之后调用processOneRpc(buf), 再调processData(buf)进行反序列化。
在processData(buf)中,通过Rpc报头获得一个Writable的实例:
Class<? extends Writable> rpcRequestClass = getRpcRequestWrapper(header.getRpcKind());... rpcRequest = ReflectionUtils.newInstance(rpcRequestClass, conf); rpcRequest.readFields(dis);
在此处,实例是 org.apache.hadoop.ipc.ProtobufRpcEngine.RpcRequestWrapper,在这里读取参数:
public void readFields(java.io.DataInput in) throws java.io.IOException { /* compiled code */ }
Call call = new Call(header.getCallId(), rpcRequest, this, ProtoUtil.convert(header.getRpcKind())); callQueue.put(call); // queue the call; maybe blocked here把整个RPC请求包装成一个Call,入队。
在Handler中主循环取出Call以后有:
// Make the call as the user via Subject.doAs, thus associating // the call with the Subject if (call.connection.user == null) { value = call(call.rpcKind, call.connection.protocolName, call.rpcRequest, call.timestamp); } else { value = call.connection.user.doAs (new PrivilegedExceptionAction<Writable>() { @Override public Writable run() throws Exception { // make the call return call(call.rpcKind, call.connection.protocolName, call.rpcRequest, call.timestamp); } } ); }call继续调用getRpcInvoker获取RpcInvoker并call,这里是ProtoBufRpcInvoker,其call函数有:
ProtoClassProtoImpl protocolImpl = getProtocolImpl(server, declaringClassProtoName, clientVersion); BlockingService service = (BlockingService) protocolImpl.protocolImpl; MethodDescriptor methodDescriptor = service.getDescriptorForType() .findMethodByName(methodName);... result = service.callBlockingMethod(methodDescriptor, null, param);调用org.apache.hadoop.hdfs.protocol.proto,ClientNamenodeProtocolProtos.ClientNamenodeProtocol一个匿名类中的callBlockingMethod:
... switch(method.getIndex()) { case 0: return impl.getBlockLocations(controller, (org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.GetBlockLocationsRequestProto)request);通过MethodDescriptor获取方法,调用impl的对应方法,此处impl即ClientNamenodeProtocolServerSideTranslatorPB,在NamenodeRpcServer初始化的时候将其注册为Translator。在ClientNamenodeProtocolServerSideTranslatorPB中有如下:
public GetBlockLocationsResponseProto getBlockLocations( RpcController controller, GetBlockLocationsRequestProto req) throws ServiceException { try { LocatedBlocks b = server.getBlockLocations(req.getSrc(), req.getOffset(), req.getLength()); Builder builder = GetBlockLocationsResponseProto .newBuilder(); if (b != null) { builder.setLocations(PBHelper.convert(b)).build(); } return builder.build(); ...通过req获取各个参数以后调用server的方法,server即本文开始处的NamenodeRpcServer,一切Namenode的RPC请求最终都提交到此。
总结下,我们了解了一个RPC请求从java的TCP层到NamenodeRpcServer的调用过程,因为要做转发请求的工作,请求的回复以及请求的发起方式都是接下来要继续了解的内容。
EOF
- HDFS Namenode接收RPC请求过程
- NameNode 接收请求
- HDFS中NameNode启动过程
- RPC请求处理过程
- RPC请求处理过程
- HDFS之NameNode的启动过程分析
- 四、HDFS中NameNode的启动过程
- hdfs中NameNode启动过程介绍
- HDFS---Namenode
- hdfs namenode
- Linux内核RPC请求过程
- NFS客户端RPC请求封装过程
- NFS客户端RPC请求封装过程
- 阿里巴巴面试题,rpc请求保序接收算法
- HDFS------hadoop namenode -format
- HDFS------namenode 初始化
- HDFS之NameNode分析
- HDFS namenode源码分析
- Android OMX 01
- 关于Vmware装的过程中出现的vmware workstation _x64.msi failed问题
- JBPM4.4(一) jbpm环境搭建以及同ssh整合
- IOS开发(三)
- CDialogBar中对按钮等控件EnableWindow操作问题
- HDFS Namenode接收RPC请求过程
- c++学习之标准库异常类
- Virtualbox中的XP虚拟机和主机Win7之间的共享文件夹
- oracle自动共享内存管理(ASMM) .
- svn报Could not read status line: connection was closed by server(不能读状态行: 连接被服务器关闭)
- HTTP POST GET 本质区别详解
- spring_aop_annotaion
- NSArray和 Vector<struct>互转
- 標準C++的類型轉換:static_cast、dynamic_cast