spark rpc简述

Spark2 rpc

一、前言

Spark在1.6之前的通信使用的是akka框架,在1.6可选用akka还是netty,2.0之后摒弃akka。Akka也是一个优秀的框架,为什么摒弃它官方给出的原因如下:

1、很多Spark用户自己也是使用Akka,但是由于Akka版本之间无法互相通信,这就要求用户必须使用跟Spark完全相同的版本,导致用户无法升级Akka。

2、Spark用的Akka配置是针对Spark自身来调优的,可能跟用户自己代码中的Akka配置冲突。

3、Spark用的Akka特性很少,这部分特性很容易自己实现,同时这部分代码量相比Akka来说少很多,debug比较容易。如果遇到什么bug,也可以自己马上fix,不需要等到Akka上游发布新版本。而且Spark审计Akka本身因为第一点会强制要求用户升级他们的Akka版本,对某些用户来说这代价是比较昂贵的或者是不太现实的。

二、通信组件概览

 

 

 

RpcEnv:RPC环境,每个Rpc端点运行时依赖的环境

RPCEndpoint:RPC端点,Spark将每个通信实体都称之为一个Rpc端点,且都实现RpcEndpoint接口,内部根据不同端点的需求,设计不同的信息和不同的业务处理。

RpcEndpointRef:一个对RpcEndpoint的远程应用对象,通过它可以想远程端点发送信息一进行通信。

如果想要与一个RpcEndpoint端进行通信,一定需要获取到该RpcEndpoint一个RpcEndpointRef,通过RpcEndpointRef与RpcEndpoint进行通信,只能通过一个RpcEnv环境对象来获取RpcEndpoint对应的RpcEndpointRef。

客户端通过RpcEndpointRef发消息,首先通过RpcEnv来处理这个消息,找到这个消息具体发给谁,然后路由给RpcEndpoint实体。

Dispatcher:消息分发器,负责将RpcMessage分发至对应的RpcEndpoint。其包含一个Meseageloop,它读取LinkedBlockingQueue中投递的的RpcMessage,根据客户端指定的Endpoint表示,找到Endpoint的Inbox,然后投递进去,由于是阻塞队列,当没有消息的时候自然阻塞,一旦有消息,就开始工作。Dispatcher的ThreadPool负责消费这些message。

Inbox:一个本地端点对应一个收件箱,Inbox里面有一个InboxMessage的链表,InboxMessage有很多子类,可以是远程调用过来的RpcMessage,可以是远程调用过来的fire-and-forget的单向消息OneWayMessage,还可以是各种服务启动、链路建立断开等Message,这些message都会在Inbox内部的方法内做模式匹配,调用相应的RpcEndpoint的函数。

Outbox:一个远程端点对应一个收件箱,NettyRpcEnv中包含一个ConcurrentHashMap[RpcAddress,Outbox]。当消息放入Outbox后,紧接着将消息通过TransportClient发送出去

TranSportClient:Netty通信客户端,一个Outbox对应一个TranSportClient,根据Outbox消息的receiver消息,请求对应远程TranSportClient。

TranSportServer:Netty通信服务端,一个Rpc端点对应一个TranSportServer,接远程消息后调用Dispatcher分发消息至对应的收发件箱。

三、通信

 

 

 

 

EndPoint启动后,默认会向Inbox中添加Onstart消息,不同的端点消费Onstart指令时,进行相关端点的启动处理流程。

Endpoint启动时,会默认启动TranSportServer,且启动结束后会进行一次同步测试可用性。

Dispatcher作为一个分发器,内部存放了Inbox句柄和状态数据(outboxes在NettyRpcEnv中)

在构建Dispatcher时会创建一个线程池,该线程池循环从receivers阻塞队列中取出EndpointData处理,如果receivers中没有EndpointData,就阻塞。有EndpointData就从该EndpointData的Inbox中取出消息消费。

 

 

posted @ 2019-09-09 09:54  力扛九鼎  阅读(344)  评论(0编辑  收藏  举报