3.1 Spark 通信架构概述
3.1 Spark 通信架构概述
Spark 中通信框架的发展:
➢ Spark 早期版本中采用 Akka 作为内部通信部件。
➢ Spark1.3 中引入 Netty 通信框架,为了解决 Shuffle 的大数据传输问题使用
➢ Spark1.6 中 Akka 和 Netty 可以配置使用。Netty 完全实现了 Akka 在 Spark 中的功能。
➢ Spark2 系列中,Spark 抛弃 Akka,使用 Netty。
什么是Akka?
Akka是一个开源的工具包和运行时,用于在Java虚拟机(JVM)上构建高度并发、分布式和容错的应用程序。它提供了一种编程模型和一组工具,简化了并发和分布式系统的开发。
Akka基于Actor模型,Actor模型是一种用于并发计算的数学模型。在Akka中,Actor是基本的构建块。Actor是轻量级、独立的实体,它们通过发送消息来相互通信。它们封装了状态和行为,每个Actor按顺序处理消息。
Akka的一个关键特点是它能够处理并发性和可扩展性。Akka的Actor可以分布在多台机器上,形成一个集群,它们可以无缝地进行通信,无论它们的物理位置如何。这使得可以开发出高度可扩展和容错的系统。
什么是Netty?
Netty是一个开源的、高性能的网络应用程序框架,用于快速开发可扩展的、高性能的网络服务器和客户端应用。它是基于Java NIO(New I/O)技术构建的,提供了异步的、事件驱动的网络编程模型。
Netty的设计目标是提供简单、高效、稳定的网络编程框架。它抽象了底层网络通信的细节,提供了易于使用的API,使开发者能够专注于业务逻辑而不必过多关注网络通信的复杂性。
Netty的核心组件是Channel(通道),它代表了网络通信的双向数据流。通过Channel,应用程序可以读取和写入数据,进行网络操作。Netty还提供了一组处理器(Handlers),用于处理数据的编解码、协议解析、业务逻辑等操作。开发者可以根据需要组合这些处理器来构建自己的网络应用程序。
Netty具有高性能和可扩展性的优势,它采用了异步、非阻塞的I/O模型,通过事件驱动的方式处理网络请求,能够支持大量并发连接和高吞吐量的数据传输。同时,Netty还提供了丰富的功能和扩展点,可以满足各种复杂的网络应用需求,如实现各种协议、构建高性能的服务器和客户端等。
总之,Netty是一个强大的网络应用程序框架,它简化了网络编程的复杂性,提供了高性能和可扩展性,使开发者能够快速构建可靠的网络应用程序。
Spark2.
x 版本使用 Netty 通讯框架作为内部通讯组件。Spark 基于 Netty 新的 RPC 框架
借鉴了 Akka 的中的设计,它是基于 Actor 模型,如下图所示:
Spark 通讯框架中各个组件(Client/Master/Worker)可以认为是一个个独立的实体,各
个实体之间通过消息来进行通信。具体各个组件之间的关系图如下:
- Endpoint(Client/Master/Worker)有 1 个 InBox 和 N 个 OutBox(N>=1,N 取决于当前 Endpoint与多少其他的 Endpoint 进行通信,一个与其通讯的其他 Endpoint 对应一个 OutBox),Endpoint接收到的消息被写入 InBox,发送出去的消息写入 OutBox 并被发送到其他 Endpoint 的 InBox中。
Spark 通信终端
Driver:
class DriverEndpoint extends IsolatedRpcEndpoint
Executor
class CoarseGrainedExecutorBackend extends IsolatedRpcEndpoint
IsolatedRpcEndpoint类
"IsolatedRpcEndpoint"是Akka框架中的一个类,用于实现独立的远程过程调用(RPC)端点。
在Akka中,远程过程调用是指通过网络在不同的系统或进程之间进行方法调用和消息传递。"IsolatedRpcEndpoint"提供了一种机制,可以在分布式系统中创建可独立运行的RPC端点。它允许开发者定义自己的端点逻辑,并与其他系统进行通信。
"IsolatedRpcEndpoint"类提供了以下功能和特性:
-
独立性:每个IsolatedRpcEndpoint都在自己的Actor中运行,与其他端点相互隔离,从而确保各个端点之间的状态和行为不会相互影响。
-
生命周期管理:IsolatedRpcEndpoint提供了生命周期管理方法,可以在启动、停止和重启端点时执行相应的操作。
-
消息处理:端点可以接收和处理来自其他系统的消息,并根据需要发送响应。开发者可以实现自己的消息处理逻辑,根据接收到的消息执行相应的操作。
-
异常处理:IsolatedRpcEndpoint提供了异常处理机制,可以捕获和处理发生在端点内部的异常情况。
通过使用"IsolatedRpcEndpoint",开发者可以方便地构建分布式系统中的独立RPC端点,并实现与其他系统之间的通信。这样可以提高系统的可扩展性、容错性和并发性,并简化分布式系统的开发和管理过程。
3.2 Spark 通讯架构解析
Spark 通信架构如下图所示:
➢ RpcEndpoint:RPC 通信终端。Spark 针对每个节点(Client/Master/Worker)都称之为一
个 RPC 终端,且都实现 RpcEndpoint 接口,内部根据不同端点的需求,设计不同的消
息和不同的业务处理,如果需要发送(询问)则调用 Dispatcher。在 Spark 中,所有的
终端都存在生命周期:
⚫ Constructor
⚫ onStart
⚫ receive*
⚫ onStop
➢ RpcEnv:RPC 上下文环境,每个 RPC 终端运行时依赖的上下文环境称为 RpcEnv;在
把当前 Spark 版本中使用的 NettyRpcEnv
➢ Dispatcher:消息调度(分发)器,针对于 RPC 终端需要发送远程消息或者从远程 RPC
接收到的消息,分发至对应的指令收件箱(发件箱)。如果指令接收方是自己则存入收
件箱,如果指令接收方不是自己,则放入发件箱;
➢ Inbox:指令消息收件箱。一个本地 RpcEndpoint 对应一个收件箱,Dispatcher 在每次向
Inbox 存入消息时,都将对应 EndpointData 加入内部 ReceiverQueue 中,另外 Dispatcher
创建时会启动一个单独线程进行轮询 ReceiverQueue,进行收件箱消息消费;
➢ RpcEndpointRef:RpcEndpointRef 是对远程 RpcEndpoint 的一个引用。当我们需要向一
个具体的 RpcEndpoint 发送消息时,一般我们需要获取到该 RpcEndpoint 的引用,然后
通过该应用发送消息。
➢ OutBox:指令消息发件箱。对于当前 RpcEndpoint 来说,一个目标 RpcEndpoint 对应一
个发件箱,如果向多个目标RpcEndpoint发送信息,则有多个OutBox。当消息放入Outbox
后,紧接着通过 TransportClient 将消息发送出去。消息放入发件箱以及发送过程是在同
一个线程中进行;
➢ RpcAddress:表示远程的 RpcEndpointRef 的地址,Host + Port。
➢ TransportClient:Netty 通信客户端,一个 OutBox 对应一个 TransportClient,TransportClient
不断轮询 OutBox,根据 OutBox 消息的 receiver 信息,请求对应的远程 TransportServer;
➢ TransportServer:Netty 通信服务端,一个 RpcEndpoint 对应一个 TransportServer,接受
远程消息后调用 Dispatcher 分发消息至对应收发件箱;