结合其他文章

http://weixiaolu.iteye.com/blog/1504898

https://www.cnblogs.com/dycg/p/3934394.html

https://blog.csdn.net/c929833623lvcha/article/details/49052845

和自己看的,记录下

如何用?

实现 VersionedProtocol 定义方法
Server server = new RPC.Builder(conf).setProtocol(TestProtocol.class)
.setInstance(new TestProtocolImpl()).setBindAddress(ADDRESS).setPort(0)
.build();
server.start();
-----------------------------------------------------------------------------------------
TestProtocol proxy = RPC.getProxy(TestProtocol.class,TestProtocol.versionID,addr, conf);
proxy.调用定义的方法

如何实现?

Service:

先从启动看起,包含了Responder/Listener/Handler[],他们分别处理Nio过程中的不同步骤

  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();
}
}

觉得别人写的不错,抄自:https://www.cnblogs.com/zhixingheyi2016/p/8781006.html

服务端使用了四组线程

Listener:

单个线程,用于监听连接,持有selector ,然后从 Reader[]线程组内挑选一个线程接受监听好的SelectionKey

// 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();
}

Reader[]:

reader 线程组负责读取连接上的读请求,并传递给 Handler线程组,每个线程持有一个readSelector

 void doRead(SelectionKey key) throws InterruptedException {
int count;
Connection c = (Connection)key.attachment();
......try {
//处理读
count = c.readAndProcess();
} catch (InterruptedException ieo) {
}
    private void processOneRpc(ByteBuffer bb)
throws IOException, InterruptedException {try {
......
callId = header.getCallId();
......final RpcCall call = new RpcCall(this, callId, retry);
setupResponse(call,
rse.getRpcStatusProto(), rse.getRpcErrorCodeProto(), null,
t.getClass().getName(), t.getMessage());
sendResponse(call);
}
}

Handler[]:

hander 线程组负责处理请求并返回响应,未能成功返回的响应交Responder

  private class Handler extends Thread {
public Handler(int instanceNumber) {
this.setDaemon(true);
this.setName("IPC Server handler "+ instanceNumber + " on " + port);
} @Override
public void run() {
LOG.debug(Thread.currentThread().getName() + ": starting");
SERVER.set(Server.this);
while (running) {
TraceScope traceScope = null;
try {
final Call call = callQueue.take(); // pop the queue; maybe blocked here
...
call.run();
}
}
}
}

Responder:

持有一个writeSelector,监听写事件

对于其中的Call对象 :该类封装了一个RPC请求,它主要包含唯一标识id,函数调用信息、函数执行返回值value,异常信息error和执行完成标识done。由于HadoopRPCServer采用了异步方式处理客户端请求,这使得远程过程调用的发生顺序与结果返回顺序无直接关系,而Client端正是通过id识别不同的函数调用。当客户端向服务端发送请求时,只需要填充id和param这两个变量,而剩下的三个变量:value,error,done,则由服务端根据函数执行情况填充.

对于Connection, 用于Client与每个Server之间维护一个通信连接。该连接相关的基本信息及操作被封装到Connection类中,其中基本信息主要包括:通信连接唯一标识remoteId,与Server端通信的Socket,网络输入流in,网络输出流out,保存RPC请求的哈希表calls等.

public class Connection {
    private Socket socket;private LinkedList<RpcCall> responseQueue;
......

Invoker的invoke方法

        val = (RpcWritable.Buffer) client.call(RPC.RpcKind.RPC_PROTOCOL_BUFFER,
new RpcProtobufRequest(rpcRequestHeader, theRequest), remoteId,
fallbackToSimpleAuth);

客户端设计

client.call
  Writable call(RPC.RpcKind rpcKind, Writable rpcRequest,
ConnectionId remoteId, int serviceClass,
AtomicBoolean fallbackToSimpleAuth) throws IOException {
final Call call = createCall(rpcKind, rpcRequest);
final Connection connection = getConnection(remoteId, call, serviceClass,
fallbackToSimpleAuth); connection.sendRpcRequest(call); // send the rpc request

对于客户端和服务端的交互

Invoker :动态代理,起始就是为了在invoke中实现具体的客户端访问逻辑,实现网络调用

    @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
try {
value = (ObjectWritable)
client.call(RPC.RpcKind.RPC_WRITABLE, new Invocation(method, args),
remoteId, fallbackToSimpleAuth);
} finally {
if (traceScope != null) traceScope.close();
}

Invocation :用于封装方法名和参数,作为数据传输层

hadoop-1的更多相关文章

  1. Hadoop 中利用 mapreduce 读写 mysql 数据

    Hadoop 中利用 mapreduce 读写 mysql 数据   有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...

  2. 初识Hadoop、Hive

    2016.10.13 20:28 很久没有写随笔了,自打小宝出生后就没有写过新的文章.数次来到博客园,想开始新的学习历程,总是被各种琐事中断.一方面确实是最近的项目工作比较忙,各个集群频繁地上线加多版 ...

  3. hadoop 2.7.3本地环境运行官方wordcount-基于HDFS

    接上篇<hadoop 2.7.3本地环境运行官方wordcount>.继续在本地模式下测试,本次使用hdfs. 2 本地模式使用fs计数wodcount 上面是直接使用的是linux的文件 ...

  4. hadoop 2.7.3本地环境运行官方wordcount

    hadoop 2.7.3本地环境运行官方wordcount 基本环境: 系统:win7 虚机环境:virtualBox 虚机:centos 7 hadoop版本:2.7.3 本次先以独立模式(本地模式 ...

  5. 【Big Data】HADOOP集群的配置(一)

    Hadoop集群的配置(一) 摘要: hadoop集群配置系列文档,是笔者在实验室真机环境实验后整理而得.以便随后工作所需,做以知识整理,另则与博客园朋友分享实验成果,因为笔者在学习初期,也遇到不少问 ...

  6. Hadoop学习之旅二:HDFS

    本文基于Hadoop1.X 概述 分布式文件系统主要用来解决如下几个问题: 读写大文件 加速运算 对于某些体积巨大的文件,比如其大小超过了计算机文件系统所能存放的最大限制或者是其大小甚至超过了计算机整 ...

  7. 程序员必须要知道的Hadoop的一些事实

    程序员必须要知道的Hadoop的一些事实.现如今,Apache Hadoop已经无人不知无人不晓.当年雅虎搜索工程师Doug Cutting开发出这个用以创建分布式计算机环境的开源软...... 1: ...

  8. Hadoop 2.x 生态系统及技术架构图

    一.负责收集数据的工具:Sqoop(关系型数据导入Hadoop)Flume(日志数据导入Hadoop,支持数据源广泛)Kafka(支持数据源有限,但吞吐大) 二.负责存储数据的工具:HBaseMong ...

  9. Hadoop的安装与设置(1)

    在Ubuntu下安装与设置Hadoop的主要过程. 1. 创建Hadoop用户 创建一个用户,用户名为hadoop,在home下创建该用户的主目录,就不详细介绍了. 2. 安装Java环境 下载Lin ...

  10. 基于Ubuntu Hadoop的群集搭建Hive

    Hive是Hadoop生态中的一个重要组成部分,主要用于数据仓库.前面的文章中我们已经搭建好了Hadoop的群集,下面我们在这个群集上再搭建Hive的群集. 1.安装MySQL 1.1安装MySQL ...

随机推荐

  1. 运用PowerDesigner的反向工程,可以导入SQL脚本,从而生成物理模型

    运用PowerDesigner的反向工程,可以导入SQL脚本,从而生成物理模型.方法/步骤 首先打开PowerDesigner,点击左上角“File”—>"Reverse Engine ...

  2. [UE4]场景加载界面

    就可以这样就可以了,当另外一个场景成功打开后,场景加载界面也会自动消失(因为这是加载界面是添加到当前场景). 加上delay是为了在小场景测试的时候可以方便看到加载场景,避免场景加载过快看不到,不加的 ...

  3. 动态材质实例(Dynamic Material Instance)

    转自:http://blog.csdn.net/panda1234lee/article/details/62041775 本例将通过 “靠近影响椅子的颜色” 来展示什么是 动态材质实例(Dynami ...

  4. ORACLE 通过连接查询更新 update select

    注意:  关键的地方是where 语句的加入. 在11G中, 如果不加11G , 或造成除匹配的行数更新为相应的值之后, 其余的会变成负数. 所以,执行前需要测试, 普通办法就是:  先查看需要更新的 ...

  5. WebBrowser JS回调delphi的方法 (简单通用)

    上一部分讲了Delphi根据方法名调用方法,这一部分还有用到,接着上一章: [主要原理] 通过TEmbeddedWB控件的OnShowMessage事件捕获弹窗来实现,弹窗时定义方法名和参数,在捕获方 ...

  6. 用树莓派开Wifi热点

    安装软件 首先设置软件源: vim /etc/apt/sources.list 查看软件源后面的版本,如果是wheezy,需要换成jessie wheezy是基于deb 7的版本 而现在是基于jess ...

  7. 普通数组和json数组的区别

    PHP 数组 什么是数组? 数组是特殊的变量,它可以同时保存一个以上的值. 在 PHP 中创建数组 在 PHP 中, array() 函数用于创建数组 在 PHP 中,有三种数组类型: 索引数组 - ...

  8. django-request获取数据

    request 如果说 urls.py 是 Django 中前端页面和后台程序桥梁,那么 request 就是桥上负责运输的小汽车 可以说后端接收到的来至前端的信息几乎全部来自于requests中. ...

  9. Sebastian Ruder : NLP 领域知名博主博士论文面向自然语言处理的神经网络迁移学习

    Sebastian Ruder 博士的答辩 PPT<Neural Transfer Learning for Natural Language Processing>介绍了面向自然语言的迁 ...

  10. linux文件基本权限-基本权限的修改

    基本权限的修改 当我们在linux或unix系统的terminal输入"ls -l"命令时,将输出文件的详细信息.第一列,如“drwxr-xr-x”就是文件的权限信息. yinti ...