大数据,机器学习,人工智能hadoop 大数据底层理解

Spark netty RPC 通信原理

2022-05-19  本文已影响0人  Tim在路上

Spark netty RPC 通信原理

通信是分布式程序的血液和神经,就好比大脑发出的执行需要通过神经和需要才能传递到手脚进行执行。可见好的通信能力是分布式系统的重重之中。

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

回顾Spark的通信的进化史,在Spark1.6之前,Spark的Rpc是基于Akka来实现通信的。(Akka是一个基于scala语言的比较先进异步通信的消息框架)但由于Akka不适合大文件的传输,其大文件是基于Jetty实现的HttpFileServer实现。但随着spark社区的发展,在Spark1.6中移除了Akka https://issues.apache.org/jira/plugins/servlet/mobile#issue/SPARK-5293),原因概括为:

  1. 很多Spark用户也使用Akka,但是由于Akka不同版本之间无法互相通信,这就要求用户必须使用跟Spark完全一样的Akka版本,导致用户无法升级Akka。
  2. Spark的Akka配置是针对Spark自身来调优的,会跟用户自己代码中的Akka配置冲突。
  3. Spark用的Akka特性很少,这部分特性很容易自己实现。同时,这部分代码量相比Akka来说很少,如果自己实现,那么debug比较容易,遇到什么bug,也可以马上fix,不需要等Akka上游发布新版本。

综上,在Spark2.xx中,spark基于netty,参照akka实现了Spark自己的RPC通信框架。

目前在spark中通信模块主要在core和network-common 模块中。 core 主要定义了RpcEnv, Endpoint, EndpointRef 等通信上层的实现,这部分基本是仿照Akka实现的, 在Spark-network-common主要实现了TransportClient, TransportServer等底层netty的通信模块。

1. Akka 通信系统架构

Akka 通过消息传递实现并发处理,规避了复杂的thread和私有数据,异步通信,事件响应等处理。

  1. 保持数据隔离并绑定到线程。线程应该隐藏(封装)它们的私有数据和其他资源,而不是与系统的其余部分共享它们。
  2. 通过消息(事件对象)在线程之间异步通信。使用异步事件可以使线程真正独立地运行,而不会相互阻塞。
  3. 线程应该将其生命周期用于响应传入事件,因此它们的主线应该由一个事件循环组成,该循环一次处理一个事件(直到完成),从而避免线程本身内的任何并发危险。

在java的并发开发实质上是通过thread+lock实现,而akka 是通过消息不可变更和通信实现。 Akka的特点是1. 每个Actor自己的内部功能都是被串行执行的。2. Actor之间是通过底层的线程池来实现并行。

[图片上传失败...(image-a95df3-1646009602027)]

在Akka中重要是actor模型和 mailBox 通信系统,每一个Actor都维护一个Mailbox, 既可以收发消息。具体的执行则有维护的线程池进行执行。Spark通信框架中各个组件(Client/Master/Worker)可以认为是一个个独立的实体,各个实体之间通过消息来进行通信。

2. Spark 通信系统架构

在Spark 中每一个实体(Client, Master, Worker)都可以认为是一个Actor, 其都会维护一个收件箱(inBox)和多个发件箱(OutBox)。

[图片上传失败...(image-70d8f7-1646009602027)]

如图所示,在spark中Endpoint 就相当于Akka中的Actor 。Endpoint有 1 个 InBox 和 N 个 OutBox(N>=1,N取决于当前 Endpoint 与多少其他的 Endpoint 进行通信,一个与其通讯的其他Endpoint 对应一个 OutBox),Endpoint 接收到的消息被写入 InBox,发送出去的消息写入 OutBox 并被发送到其他 Endpoint 的 InBox 中。

了解了Spark实现akka的通信原理进行节点间通信与并发处理。简述下Spark的通信系统,在Spark的上层是使用RpcEndpoint, RpcEndPointRef, Dispatcher 等作为Actor系统,inBox和outBox 实现mailBox。 而在底层进行远程消息投递的rpc调用中是通过TransportClient 和 TransportServer 实现底层远程rpc通信。

[图片上传失败...(image-6988c8-1646009602027)]

TransportServer 接受远程发送的消息 → Dispatcher → inbox → Async 消费

RpcEndpointRef 客户端 → RpcEnv→ OutBox → TransportClient 发送到TransportServer.

3. Spark 通信系统重要概念介绍

[图片上传失败...(image-fb8eef-1646009602026)]

上图是Spark 通信系统最重要的类的关系图,从中可以看出在Actor系统中最重要的是NettyRpcEnv, 在Netty的通信系统中最重要的是TransportContext。

Actor 体系:

Transport体系:

Messages系统:

上一篇下一篇

猜你喜欢

热点阅读