Flink-源码学习-通信服务-Flink RPC 设计
一、概述
Flink 内部组件之间的通信是用 Akka,比如 JobManager 和 TaskManager 之间的通信。而 Operator 之间的数据传输则利用 Netty 为不同的应用层通信协议 (RPC, FTP, HTTP 等) 提供支持。
1.1. Akka 概述
Akka 是一套开源库,用于设计跨处理器和跨网络的可扩展弹性系统,借助 Akka 可以专注于满足业务需求,而不是编写底层代码来提供可靠的行为、容错和高性能。
二、Flink RPC 架构
Flink 集群内部通信框架的最底层依赖于 Akka,定义了不同类型的消息,并且设计了通用的 RPC 通信组件,Flink 的所有提供 RPC 请求的集群组件(如 JobMaster、 TaskManager、 ResourceManager、 Dispatcher 等)都使用了这些 RPC 通信基础组件来提供对外的 RPC 接口。
Flink 集群运行时中实现了 RPC 通信节点功能的主要有 Dispatcher、 ResourceManager 和 TaskManager 以及 JobMaster 等组件。借助 RPC通信,这些组件共同参与任务提交及运行的整个流程。
举个栗子🌰~~~
通过客户端向 Dispatcher 服务提交 JobGraph,JobManager 向 TaskManager 提交 Task 请求,以及 TaskManager 向JobManager 更新 Task 执行状态等。
Flink 通过动态代理对 Akka 中的 Actorsystem、 Actor 进行了 封装和使用,抽象了 RpcService, RpcEndpoint, RpcGateway, RpcServer 接口。
接口 | 含义 |
---|---|
RpcGateway | 用于远程调用的代理接口,RpcGateway 接口提供了获取其代理 RpcEndpoint 的地址的方法。在实现一个提供 RPC 调用的组件时,通常需要先定一个接口,该接口继承 RpcGateway 并约定提供的远程调用的方法。(相当于 Akka 的 ActorRef 对象) |
RpcServer | RpcEndpoint 包含一个内置的 RpcServer 负责执行本地和远程的代码请求,相当于 RpcEndpoint 自身的代理对象,RpcService 在启动 RpcEndpoint 的时候返回 RpcServer。 |
RpcEndpoint | RpcEndpoint 是通信终端,提供 RPC 服务组件的生命周期管理(start、stop),所有需要实现 RPC 服务的组件都会继承 RpcEndpoint 抽象类。每个 RpcEndpoint 对应了一个路径(由 endpointid 和 actorSystem 共同确定),用于唯一标记当前的 RPC 节点。每个路径对应一个Actor,其实现了 RpcGateway 接口(相当于 Akka 的 Actor 对象) |
RpcService | RpcEndpoint 的运行时环境 (相当于 Akka 的 ActorSystem 对象) |
2.1. RpcService
RpcService 是对 Akka 中 ActorSystem 的封装。正如一个 ActorSystem 系统中有多个 Actor,同样在 Flink 中一个 RpcService 中有多个 Rpc 服务。
RpcService 类似于 Spark 通信架构中 RpcEnv 的角色 !
2.2. 客户端
请求程序
请求程序会像调用本地方法一样调用客户端 Stub 程序,然后接收 Stub 程序返回的响应信息。
Stub 程序
客户端的 Stub 会将请求程序的 RPC 调用序列化,并调用方法将这个请求发送给远程服务器,这些实现对于客户端调用程序是完全透明的。
传输层-client
Akka 支持多种传输协议用于进程间的通信.单进程 Actor 系统默认协议是
akka://
如果使用的远程或者集群,则通常会使用akka.tcp://
或者akka.udp://
在节点之间进行通信
2.3. 服务端 RpcServer
传输层-server(receive)
Akka 支持多种传输协议用于进程间的通信.单进程 Actor 系统默认协议是
akka://
如果使用的远程或者集群,则通常会使用akka.tcp://
或者akka.udp://
在节点之间进行通信。Akka 中 创建 actor 需要继承 AbstractActor 类并重写它的初始行为方法 createReceive(),actor 接收消息后会触发 createReceive() 方法被调用,通过 receiveBuilder() 来接收消息以及它的类型,从而判断该如何处理消息。
Stub 程序
服务器端 Stub 程序会将通信模块接收的数据反序列化,然后调用服务程序对应的方法响应 RPC 请求。
服务程序
服务器会接收来自 Stub 程序的调用请求,执行对应的逻辑并返回执行结果。
三、总结
3.1. onStart 消息处理
当在任意地方发现要创建这四个组件的任何一个组件的实例对象的时候,创建成功了之后,都会要去执行他的 onStart()