一、概述

在 Spark 中很多地方都涉及网络通信,比如 Spark 各个组件间的消息互通 用户文件与 Jar 包的上传、节点间的 Shuffle 过程、Block 数据的复制与备份等。

1.1. 分布式通信概述

1.2. Spark RPC

在 Spark 2.x 版本之前,组件间的消息通信主要借助于 Akka,使用 Akka 可以轻松地构建强有力的高并发与分布式应用。但是Akka 在 Spark 2.0.0 版本中被移除了。

Spark 官网文档对此的描述为 Akka 的依赖被移除了,因此用户可以使用任何版本的 Akka 来编程 Spark 团队的决策者或许认为对 Akka 具体版本的依赖,限制了用户对 Akka 不同版本的使用主要原因是解决用户的Spark Application 中 Akka 版本和 Spark 内置的 Akka版本冲突的问题。

1.2.1. Akka

Akka 是基于 Actor 的 RPC 通信系统

1.2.2. Netty

二、Spark RPC 架构设计

2.1. RPCEnv

RpcEnv 是 Spark 2.x 版本中推出的组件,RpcEnv 组件肩负着另一项历史使命替代 Spark 2.x 以前版本中采用的 Akka。Spark 通信架构中最核心的就是 RpcEnv, 类似于 akka 中的 ActorSystem, 服务端和客户端都可以使用它来做通信。

RpcEnv 是各个组件之间通信的执行环境,每个节点之间(Driver 或者 Worker/Executor) 组件的 Endpoint 和对应的 EndpointRef 之间的信息通信和方法调用都是通过 RpcEnv 作协调。

2.2. 客户端设计

客户端请求程序通过本地调用的方式调用服务,服务调用过程中,真正的方法逻辑存在于服务端中,客户端保存就是服务端真实方法的一个存根 stub(也可以认为是服务端的代理,存放服务端的地址等信息); 当客户端需要远程访问服务端方法的时候,可以凭借服务端在客户端中的存根来组装发起远程调用所需要的信息。Spark 远程通信全部使用 netty 进行了替换, TransportClientFactory 是 RPC 客户端的工厂类。

2.3. 服务端设计

服务器会接收来自 Stub 程序的调用请求,进行消息解包,调用本地方法,执行对应的逻辑。