Spark2.3.3源码解析——RPC框架初始化详解

      作为分布式系统的spark rpc通信是一个很重要的课题。在spark2.3.3版本中rpc框架已经由akka替换成netty实现。接下来我们先介绍一下spark rpc中的组件,然后根据sparkcontext初始化过程来分析rpc组件如何初始化和使用原理。

       在spark中定义transportclient和transportserver来封装netty的channel和handler,定义box来封装bytebuf,所以spark rpc有两个重要过程初始化和通信。

一、RpcEnv初始化

 

      sparkcore所有的初始化都是从sparkcontext开始,如下图,transportclient的初始化也是在sparkContext中。

      这里的RpcEnv是一个抽象类,真正实现类是NettyRpcEnv。在NettyRpcEnv中包含了RPC通信的所有操作方法,当然也有创建transportclient所需要的参数以及createClient方法。

private[netty] class NettyRpcEnv(
    val conf: SparkConf,
    javaSerializerInstance: JavaSerializerInstance,
    host: String,
    securityManager: SecurityManager,
    numUsableCores: Int) extends RpcEnv(conf) with Logging {
  private[netty] val transportConf = SparkTransportConf.fromSparkConf(
    conf.clone.set("spark.rpc.io.numConnectionsPerPeer", "1"),
    "rpc",
    conf.getInt("spark.rpc.io.threads", 0))
  private val dispatcher: Dispatcher = new Dispatcher(this, numUsableCores)
  private val streamManager = new NettyStreamManager(this)
  private val transportContext = new TransportContext(transportConf,
    new NettyRpcHandler(dispatcher, this, streamManager))
  private def createClientBootstraps(): java.util.List[TransportClientBootstrap] = {
    if (securityManager.isAuthenticationEnabled()) {
      java.util.Arrays.asList(new AuthClientBootstrap(transportConf,
        securityManager.getSaslUser(), securityManager))
    } else {
      java.util.Collections.emptyList[TransportClientBootstrap]
    }
  }
  private val clientFactory = transportContext.createClientFactory(createClientBootstraps())
  @volatile private var fileDownloadFactory: TransportClientFactory = _
  val timeoutScheduler = ThreadUtils.newDaemonSingleThreadScheduledExecutor("netty-rpc-env-timeout")
  @volatile private var server: TransportServer = _
  private val stopped = new AtomicBoolean(false)
  private val outboxes = new ConcurrentHasMp[RpcAddress, Outbox]()

先来看一段NettyRpcEnv的参数初始化代码(有删减)。这里的初始化参数都有很重要的作用:

    • transportConf :通信配置参数
    • streamManager :流管理器
    • transportContext :通信上下文
    • dispatcher:netty handler中实际高性能异步处理消息的组件,从代码中可以看到disatcher已经封装到了nettyRpcHandler中,后面会重点讲这个的作用
    • clientFactory :创建transportclient工厂在传参的时候有一个createClientBootstraps方法,这个其实是在创建client的时候做一些补充handler比如权限校验
    • outboxes :需要传递的消息盒子

二、Dispatcher初始化

       在NettyRpcEnv对象创建的时候会直接初始化dispatcher。dispatcher里面有一个内部类用来封装rpcEndpoint、rpcEndpointRef、inbox的EndpointData。RpcEndpoint是消息处理终端属于服务端,RpcEndpointRes属于客户端代表消息终端引用。其中存储的消息是inbox和outbox这里面存储了一个message序列代表所有发送和收到的消息。

private[netty] class Dispatcher(nettyEnv: NettyRpcEnv, numUsableCores: Int) extends Logging {

  private class EndpointData(
      val name: String,
      val endpoint: RpcEndpoint,
      val ref: NettyRpcEndpointRef) {
    val inbox = new Inbox(ref, endpoint)
  }

  private val endpoints: ConcurrentMap[String, EndpointData] =
    new ConcurrentHashMap[String, EndpointData]
  private val endpointRefs: ConcurrentMap[RpcEndpoint, RpcEndpointRef] =
    new ConcurrentHashMap[RpcEndpoint, RpcEndpointRef]

  // Track the receivers whose inboxes may contain messages.
  priva
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值