HADOOP源码分析之RPC(1)
源码位于Hadoop-common ipc包下
abstract class Server
构造Server
protected Server(String bindAddress, int port,
Class<? extends Writable> rpcRequestClass, int handlerCount,
int numReaders, int queueSizePerHandler, Configuration conf,
String serverName, SecretManager<? extends TokenIdentifier> secretManager,
String portRangeConfig)
throws IOException { //监听地址
this.bindAddress = bindAddress;
this.conf = conf;
this.portRangeConfig = portRangeConfig;
//监听端口
this.port = port;
this.rpcRequestClass = rpcRequestClass;
//处理器个数
this.handlerCount = handlerCount;
this.socketSendBufferSize = 0;
this.maxDataLength = conf.getInt(CommonConfigurationKeys.IPC_MAXIMUM_DATA_LENGTH,
CommonConfigurationKeys.IPC_MAXIMUM_DATA_LENGTH_DEFAULT);
if (queueSizePerHandler != -1) {
this.maxQueueSize = handlerCount * queueSizePerHandler;
} else {
this.maxQueueSize = handlerCount * conf.getInt(
CommonConfigurationKeys.IPC_SERVER_HANDLER_QUEUE_SIZE_KEY,
CommonConfigurationKeys.IPC_SERVER_HANDLER_QUEUE_SIZE_DEFAULT);
}
this.maxRespSize = conf.getInt(
CommonConfigurationKeys.IPC_SERVER_RPC_MAX_RESPONSE_SIZE_KEY,
CommonConfigurationKeys.IPC_SERVER_RPC_MAX_RESPONSE_SIZE_DEFAULT);
if (numReaders != -1) {
this.readThreads = numReaders;
} else {
this.readThreads = conf.getInt(
CommonConfigurationKeys.IPC_SERVER_RPC_READ_THREADS_KEY,
CommonConfigurationKeys.IPC_SERVER_RPC_READ_THREADS_DEFAULT);
}
this.readerPendingConnectionQueue = conf.getInt(
CommonConfigurationKeys.IPC_SERVER_RPC_READ_CONNECTION_QUEUE_SIZE_KEY,
CommonConfigurationKeys.IPC_SERVER_RPC_READ_CONNECTION_QUEUE_SIZE_DEFAULT); // Setup appropriate callqueue
final String prefix = getQueueClassPrefix();
this.callQueue = new CallQueueManager<Call>(getQueueClass(prefix, conf),
getSchedulerClass(prefix, conf),
getClientBackoffEnable(prefix, conf), maxQueueSize, prefix, conf); this.secretManager = (SecretManager<TokenIdentifier>) secretManager;
this.authorize =
conf.getBoolean(CommonConfigurationKeys.HADOOP_SECURITY_AUTHORIZATION,
false); // configure supported authentications
this.enabledAuthMethods = getAuthMethods(secretManager, conf);
this.negotiateResponse = buildNegotiateResponse(enabledAuthMethods); // Start the listener here and let it bind to the port
//监听器
listener = new Listener();
this.port = listener.getAddress().getPort();
connectionManager = new ConnectionManager();
this.rpcMetrics = RpcMetrics.create(this, conf);
this.rpcDetailedMetrics = RpcDetailedMetrics.create(this.port);
this.tcpNoDelay = conf.getBoolean(
CommonConfigurationKeysPublic.IPC_SERVER_TCPNODELAY_KEY,
CommonConfigurationKeysPublic.IPC_SERVER_TCPNODELAY_DEFAULT); this.setLogSlowRPC(conf.getBoolean(
CommonConfigurationKeysPublic.IPC_SERVER_LOG_SLOW_RPC,
CommonConfigurationKeysPublic.IPC_SERVER_LOG_SLOW_RPC_DEFAULT)); // Create the responder here
responder = new Responder(); if (secretManager != null || UserGroupInformation.isSecurityEnabled()) {
SaslRpcServer.init(conf);
saslPropsResolver = SaslPropertiesResolver.getInstance(conf);
} this.exceptionsHandler.addTerseLoggingExceptions(StandbyException.class);
}
Server的主要组成即Listener、
均是单独的线程,底层利用Java NIO实现(Reactor设计模式) 参考NIO系列文章:http://ifeve.com/overview/
如下是创建Listener的源码:
//创建一个ServerSocketChannel
acceptChannel = ServerSocketChannel.open();
acceptChannel.configureBlocking(false); // Bind the server socket to the local host and port
bind(acceptChannel.socket(), address, backlogLength, conf, portRangeConfig);
port = acceptChannel.socket().getLocalPort(); //Could be an ephemeral port
// create a selector;
selector= Selector.open();
readers = new Reader[readThreads];
for (int i = 0; i < readThreads; i++) {
Reader reader = new Reader(
"Socket Reader #" + (i + 1) + " for port " + port);
readers[i] = reader;
reader.start();
} // Register accepts on the server socket with the selector.
//注册channel到selector
acceptChannel.register(selector, SelectionKey.OP_ACCEPT);
this.setName("IPC Server listener on " + port);
this.setDaemon(true);
Listener线程通过Selector不断监听请求建立连接的Socket
public void run() {
LOG.info(Thread.currentThread().getName() + ": starting");
SERVER.set(Server.this);
connectionManager.startIdleScan();
while (running) {
SelectionKey key = null;
try {
getSelector().select();
Iterator<SelectionKey> iter = getSelector().selectedKeys().iterator();
while (iter.hasNext()) {
key = iter.next();
iter.remove();
try {
if (key.isValid()) {
if (key.isAcceptable())
doAccept(key);
}
} catch (IOException e) {
}
key = null;
}
} catch (OutOfMemoryError e) {
// we can run out of memory if we have too many threads
// log the event and sleep for a minute and give
// some thread(s) a chance to finish
LOG.warn("Out of Memory in server select", e);
closeCurrentConnection(key, e);
connectionManager.closeIdle(true);
try { Thread.sleep(60000); } catch (Exception ie) {}
} catch (Exception e) {
closeCurrentConnection(key, e);
}
}
LOG.info("Stopping " + Thread.currentThread().getName());
synchronized (this) {
try {
acceptChannel.close();
selector.close();
} catch (IOException e) { }
selector= null;
acceptChannel= null;
// close all connections
connectionManager.stopIdleScan();
connectionManager.closeAll();
}
}
HADOOP源码分析之RPC(1)的更多相关文章
- Hadoop2源码分析-RPC探索实战
1.概述 在<Hadoop2源码分析-RPC机制初识>博客中,我们对RPC机制有了初步的认识和了解,下面我们对Hadoop V2的RPC机制做进一步探索,在研究Hadoop V2的RPC机 ...
- Hadoop源码分析之数据节点的握手,注册,上报数据块和心跳
转自:http://www.it165.net/admin/html/201402/2382.html 在上一篇文章Hadoop源码分析之DataNode的启动与停止中分析了DataNode节点的启动 ...
- SparkRPC源码分析之RPC管道与消息类型
SparkRPC源码分析之RPC管道与消息类型我们前面看过了netty基础知识扫盲,那我们应该明白,ChannelHandler这个组件内为channel的各种事件提供了处理逻辑,也就是主要业务逻辑写 ...
- Hadoop2源码分析-RPC机制初识
1.概述 上一篇博客,讲述Hadoop V2的序列化机制,这为我们学习Hadoop V2的RPC机制奠定了基础.RPC的内容涵盖的信息有点多,包含Hadoop的序列化机制,RPC,代理,NIO等.若对 ...
- Hadoop源码分析之Configuration
转自:http://www.it165.net/admin/html/201312/2178.html org.apache.hadoop.conf.Configuration类是Hadoop所有功能 ...
- Hbase源码分析:RPC概况
RPC是hbase中Master,RegionServer和Client三者之间通信交流的纽带.了解hbase的rpc机制能够为通过源码学习hbase奠定良好的基础.因为了解了hbase的rpc机制能 ...
- hadoop源码分析(2):Map-Reduce的过程解析
一.客户端 Map-Reduce的过程首先是由客户端提交一个任务开始的. 提交任务主要是通过JobClient.runJob(JobConf)静态函数实现的: public static Runnin ...
- Hadoop源码分析之FileSystem抽象文件系统
Hadopo提供了一个抽象的文件系统模型FileSystem,HDFS是其中的一个实现. FileSystem是Hadoop中所有文件系统的抽象父类,它定义了文件系统所具有的基本特征和基本操作. Fi ...
- Hadoop源码分析之产生InputSplit文件过程
用户提交 MapReduce 作业后,JobClient 会调用 InputFormat 的 getSplit方法 生成 InputSplit 的信息. 一个 MapReduce 任务 ...
随机推荐
- java基础部分细节
访问控制修饰符 Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java支持4种不同的访问权限. 默认的,也称为 default,在同一包内可见,不使用任何修饰符. 私有的,以 ...
- v-cloak 实现vue实例未编译完前不显示
前言: 由于网速原因,(ps:之前同事无意间在网速很差的情况下测出的)在使用vue开发时,会由于vue实例还没编译成功的时候数据绑定的"Mustache"标签会闪现一下,造成不好的 ...
- Tornado(cookie、XSRF、用户验证)
--------------------Cookie操作-------------------- 1.设置Cookie 1.set_cookie(name,value,domain=Non ...
- Json作为配置文件注意事项
错误描述 在一次开发中,使用了JSON数据作为配置文件,但反序列化时总是出错,开始还以为是转义字符的问题,因为存了一个绝对路径(D:\xx\xx.json),后来测试发现竟然发现是类嵌套的问题. 解决 ...
- [C]字符串排序之-冒泡法
在oj刷题,遇见一题字符串排序题. 脑海里瞬间闪过数组排序. 思路有了,打开题解看看别人的思路,发现好多人的排序方法显得比较臃肿,可能也是我的水平不够,欣赏不来吧. 不过用冒泡法排序的时候一定要记得字 ...
- node.js 89行爬虫爬取智联招聘信息
写在前面的话, .......写个P,直接上效果图.附上源码地址 github/lonhon ok,正文开始,先列出用到的和require的东西: node.js,这个是必须的 request,然发 ...
- poj 2063完全背包
题意:给出总资金和投资年份 ,n个股票 给出股票价格和其一年的利润.问如何选择能获得最大利润. 思路:股票可以重复选择,完全背包问题,完全背包也是从01背包衍生而行的,其主要区别在于中间那层循环的次序 ...
- web服务的三大主流架构
1.远程过程调用 2.服务导向架构 3.表述性状态转移 今天在自学Spring架构时貌似发现 rest的表现.与RPC方式的最大差别,SOA方式更加关注如何去连接服务而不是去特定某个实现的细节.而re ...
- 交换机的Ethernet Channel
端口聚合也叫做以太通道(ethernet channel),主要用于交换机之间连接.由于两个交换机之间有多条冗余链路的时候,STP会将其中的几条链路关闭,只保留一条,这样可以避免二层的环 路产生.但是 ...
- SNS团队Beta阶段第六次站立会议(2017.5.27)
1.立会照片 2.每个人的工作 成员 今天已完成的工作 明天计划完成的工作 罗于婕 发音图标的改进 对界面各部分的图标进行完善.美化 龚晓婷 对于历史记录功能的测试 对于历史记录功能进一步完善 林仕庄 ...