hadoop中的RPC应用示例

hadoop中的RPC意义

      前面有讲到RPC的基础内容,还给出了一个小的示例来说明,这篇文章讲讲hadoop中的RPC是怎样使用的。
      RPC在Hadoop中是基础组件,提供分布式环境下的对象调用功能。可以把它理解成胶水,由于它的存在,分布式系统才互相进行通信。当然这个胶水可以被其它类型的胶水替换,也可以自己去做这个胶水。
      胶水很重要,不能缺少,当然如果只是把hadoop作为一个单机来运行,那要不要无所谓了。说了很多废话,总结一下就是说,RPC对分布式的hadoop而言很重要。

my code

首先说明一下,以下程序跑起来需要哪些jar包:

jdk不用说了,还有
hadoop-core
hadoop-client
hadoop-common
commons-logging
commons-collections
commons-configuration
commons-lang

1.server

package hadooprpc;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.ipc.RPC.Server;

public class MyServer {

    final static int port = 8888;

    final static String address = "127.0.0.1";

    public static void main(String args[]) {

        Proxy proxy = new Proxy();
        try {
            Server server = RPC.getServer(proxy, address, port, new Configuration());
            server.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.client

package hadooprpc;

import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;

public class Client {

    final static int port = 8888;

    final static String address = "127.0.0.1";

    public static void main(String[] args) {

        InetSocketAddress inetSocketAddress = new InetSocketAddress(address, port);

        try {

            MyJob job = (MyJob) RPC.waitForProxy(MyJob.class, MyJob.versionId, inetSocketAddress, new Configuration());
            String re = job.getInfo("zj");
            System.out.println(re);

        } catch (IOException e) {

            e.printStackTrace();
        }
    }
}

3.utils

package hadooprpc;

import org.apache.hadoop.ipc.VersionedProtocol;

public interface MyJob extends VersionedProtocol{

    long versionId = 123456;
    public String getInfo(String a);
}


package hadooprpc;

import java.io.IOException;

public class Proxy implements MyJob {

    @Override
    public String getInfo(String a) {

        return "你好: " + a;
    }

    @Override
    public long getProtocolVersion(String arg0, long arg1) throws IOException {
        return MyJob.versionId;
    }

}

可以看到整个框架和之前在讲述RPC时差不多,区别在于,hadoop将socket服务封装了,因此我们使用的时候就简单很多。

hadoop的RPC server实现

RPC.getServer()的调用指向

return new Server(instance, conf, bindAddress, port, numHandlers, verbose, secretManager);

server中的参数有

    private final boolean authorize;
    private boolean isSecurityEnabled;
    private ExceptionsHandler exceptionsHandler;
    public static final ByteBuffer HEADER = ByteBuffer.wrap("hrpc".getBytes());
    public static final byte CURRENT_VERSION = 4;
    private static final int IPC_SERVER_HANDLER_QUEUE_SIZE_DEFAULT = 100;
    private static final String IPC_SERVER_HANDLER_QUEUE_SIZE_KEY = "ipc.server.handler.queue.size";
    static int INITIAL_RESP_BUF_SIZE = 10240;
    static final String IPC_SERVER_RPC_MAX_RESPONSE_SIZE_KEY = "ipc.server.max.response.size";
    static final int IPC_SERVER_RPC_MAX_RESPONSE_SIZE_DEFAULT = 1048576;
    public static final Log LOG = LogFactory.getLog(Server.class);
    private static final Log AUDITLOG = LogFactory.getLog("SecurityLogger." + Server.class.getName());
    private static final String AUTH_FAILED_FOR = "Auth failed for ";
    private static final String AUTH_SUCCESSFULL_FOR = "Auth successfull for ";
    private static final ThreadLocal<Server> SERVER = new ThreadLocal();
    private static final Map<String, Class<?>> PROTOCOL_CACHE = new ConcurrentHashMap();
    private static final ThreadLocal<Call> CurCall = new ThreadLocal();
    private String bindAddress;
    private int port;
    private int handlerCount;
    private int readThreads;
    private Class<? extends Writable> paramClass;
    private int maxIdleTime;
    private int thresholdIdleConnections;
    int maxConnectionsToNuke;
    protected RpcInstrumentation rpcMetrics;
    private Configuration conf;
    private SecretManager<TokenIdentifier> secretManager;
    private int maxQueueSize;
    private final int maxRespSize;
    private int socketSendBufferSize;
    private final boolean tcpNoDelay;
    private volatile boolean running;
    private BlockingQueue<Call> callQueue;
    private List<Connection> connectionList;
    private Listener listener;
    private Responder responder;
    private int numConnections;
    private Handler[] handlers;
    private static int NIO_BUFFER_LIMIT = 8192;

   //它们的初始化情况为,使用构造器初始化
    this.exceptionsHandler = new ExceptionsHandler();
    this.running = true;
    this.connectionList = Collections.synchronizedList(new LinkedList());
    this.listener = null;
    this.responder = null;
    this.numConnections = 0;
    this.handlers = null;
    this.bindAddress = bindAddress;
    this.conf = conf;
    this.port = port;
    this.paramClass = paramClass;
    this.handlerCount = handlerCount;
    this.socketSendBufferSize = 0;
    this.maxQueueSize = handlerCount * conf.getInt("ipc.server.handler.queue.size", 100);
    this.maxRespSize = conf.getInt("ipc.server.max.response.size", 1048576);
    this.readThreads = conf.getInt("ipc.server.read.threadpool.size", 1);
    this.callQueue = new LinkedBlockingQueue(this.maxQueueSize);
    this.maxIdleTime = 2 * conf.getInt("ipc.client.connection.maxidletime", 1000);
    this.maxConnectionsToNuke = conf.getInt("ipc.client.kill.max", 10);
    this.thresholdIdleConnections = conf.getInt("ipc.client.idlethreshold", 4000);
    this.secretManager = secretManager;
    this.authorize = conf.getBoolean("hadoop.security.authorization", false);
    this.isSecurityEnabled = UserGroupInformation.isSecurityEnabled();
    this.listener = new Listener(this);
    this.port = this.listener.getAddress().getPort();
    this.rpcMetrics = RpcInstrumentation.create(serverName, this.port);
    this.tcpNoDelay = conf.getBoolean("ipc.server.tcpnodelay", false);
    this.responder = new Responder(this);
    if (this.isSecurityEnabled) {
        SaslRpcServer.init(conf);
    }

server.start();该指令的指向为

public synchronized void start() {
    this.responder.start();
    this.listener.start();
    this.handlers = new Handler[this.handlerCount];

    for (int i = 0; i < this.handlerCount; ++i) {
        this.handlers[i] = new Handler(this, i);
        this.handlers[i].start();
    }

}

那说明responder,listener,handler其实是线程服务。一个返回线程服务,一个监听器服务,多个处理器服务。

那么线程和线程之间的交互是怎么做到的呢?

private BlockingQueue<Call> callQueue;
private List<Connection> connectionList;

答案是通过这些队列。
————————————————————————————————
后面的代码是eclipse反编译得到的,后面的代码就不好获取。之后将会在hadoop源代码中去分析。

参考内容:

1.https://www.cnblogs.com/qq503665965/p/6708644.html
2.https://www.cnblogs.com/edisonchou/p/4285817.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值