BlockTransferService

1.1、在SparkEnv中初始化

它使用Netty提供的异步时间驱动的网络应用架构, 提供web服务及客户端,获取远程节点上Block集合

    val blockTransferService =
      new NettyBlockTransferService(conf, securityManager, bindAddress, advertiseAddress,
        blockManagerPort, numUsableCores)

1.2、在BlockManager中初始化

  • 创建RpcServer
  • 构造TransportContext
  • 创建Rpc客户端工厂TransportClientFactory
  • 创建Netty服务器TransportServer
        override def init(blockDataManager: BlockDataManager): Unit = {
            val rpcHandler = new NettyBlockRpcServer(conf.getAppId, serializer, blockDataManager)
            var serverBootstrap: Option[TransportServerBootstrap] = None
            var clientBootstrap: Option[TransportClientBootstrap] = None
            if (authEnabled) {
                serverBootstrap = Some(new SaslServerBootstrap(transportConf, securityManager))
                clientBootstrap = Some(new SaslClientBootstrap(transportConf, conf.getAppId, securityManager,
                    securityManager.isSaslEncryptionEnabled()))
            }
            transportContext = new TransportContext(transportConf, rpcHandler)
            clientFactory = transportContext.createClientFactory(clientBootstrap.toSeq.asJava)
            server = createServer(serverBootstrap.toList)
            appId = conf.getAppId
            logInfo(s"Server created on ${hostName}:${server.getPort}")
        }

1.3、获取远程shuffle文件

NettyBlockTransferService的fetchBlocks方法用于从远程拉取shuffle文件,实际利用的是NettyBlockTransferService总创建的Netty服务

        override def fetchBlocks( //获取block数据
                host: String,
                port: Int,
                execId: String,
                blockIds: Array[String],
                listener: BlockFetchingListener): Unit = {
            logTrace(s"Fetch blocks from $host:$port (executor id $execId)")
            try {
                val blockFetchStarter = new RetryingBlockFetcher.BlockFetchStarter {
                    override def createAndStart(blockIds: Array[String], listener: BlockFetchingListener) {
                        val client = clientFactory.createClient(host, port)
                        new OneForOneBlockFetcher(client, appId, execId, blockIds.toArray, listener).start()
                    }
                }

                val maxRetries = transportConf.maxIORetries()
                if (maxRetries > 0) {
                    // Note this Fetcher will correctly handle maxRetries == 0; we avoid it just in case there's
                    // a bug in this code. We should remove the if statement once we're sure of the stability.
                    new RetryingBlockFetcher(transportConf, blockFetchStarter, blockIds, listener).start()
                } else {
                    blockFetchStarter.createAndStart(blockIds, listener)
                }
            } catch {
                case e: Exception =>
                    logError("Exception while beginning fetchBlocks", e)
                    blockIds.foreach(listener.onBlockFetchFailure(_, e))
            }
        }

1.4、上传shuffle文件

NettyBlockTransferService的uploadBlock方法用于上传shuffle文件到远程Executor,实际也是利用NettyBlockTransferService中创建的Netty服务。

  • 1)创建Netty服务的客户端,客户端连接的hostname和port正是BlockManager的hostname和port
  • 2)将Block的存储级别StorageLevel和类标签序列化
  • 3)将Block的ByteBuffer转化为数据,便于序列化
  • 4)将appId、execId、blockId、metadata、转化为数组的Block封装为UploadBlock,并将其序列化为字节数组
  • 5)最终调用Netty客户端的sendRpc方法将字节数组上传,回掉函数RpcResponseCallback根据RPC的结果更改上传状态。
        override def uploadBlock(
                hostname: String,
                port: Int,
                execId: String,
                blockId: BlockId,
                blockData: ManagedBuffer,
                level: StorageLevel,
                classTag: ClassTag[_]): Future[Unit] = {
            val result = Promise[Unit]()
            val client = clientFactory.createClient(hostname, port)

            // StorageLevel and ClassTag are serialized as bytes using our JavaSerializer.
            // Everything else is encoded using our binary protocol.
            val metadata = JavaUtils.bufferToArray(serializer.newInstance().serialize((level, classTag)))

            // Convert or copy nio buffer into array in order to serialize it.
            val array = JavaUtils.bufferToArray(blockData.nioByteBuffer())

            client.sendRpc(new UploadBlock(appId, execId, blockId.toString, metadata, array).toByteBuffer,
                new RpcResponseCallback {
                    override def onSuccess(response: ByteBuffer): Unit = {
                        logTrace(s"Successfully uploaded block $blockId")
                        result.success((): Unit)
                    }
                    override def onFailure(e: Throwable): Unit = {
                        logError(s"Error while uploading block $blockId", e)
                        result.failure(e)
                    }
                })

            result.future
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值