flink内核原理学习组件通信rpc(代码片段)

oahaijgnahz oahaijgnahz     2022-12-08     330

关键词:

Flink内核原理学习之 RPC


文章目录


Java、大数据开发学习要点(持续更新中…)


一、Akka与Actor模型

  Akka是用于开发并发、容错和可伸缩应用的框架(常用于RPC通信框架),是Actor模型的实现。每个Actor都是独立的,相互间通过发送异步消息进行通信(其强大之处就在于异步)。多个Actor构成一个ActorSystem,每个Actor顺序处理消息队列中的消息,ActorSystem中共享一个线程池(这也就是为什么不建议用同步调用的原因)。
  ActorSystem能过识别消息发送给本地还是远程ActorSystem(路径)。Actor还有继承关系,父Actor可以创建子Actor(第一个Actor由ActorSystem创建),父Actor监督子Actor进行容错。
  如上文所说,第一个Actor是ActorSystem创建的,另外,我们只能通过ActorRef(Actor的引用,对原生的Actor实例进行了封装,外界不能改变内部Actor状态)来于Actor进行通信。获取Actor需要通过其路径获得其ActorRef(显然远程通信需要在路径提供ip+端口号)。Actor的两种异步通信方法为tellack,tell是异步给某个Actor发送消息而不需要返回值;ack则是异步发送消息后,通过Future对象异步回调获取返回结果。

二、RPC消息类型

  • 握手消息

RemoteHandshakeMessage: 与 Actor 握手消息
HandshakeSuccessMessage: 与 Actor 握手成功消息

  • Fenced消息

LocalFencedMessage: 本地 Fence Token 消息,在同一个JVM中的调用
RemoteFencedMessage: 远程 Fence Token 消息,包括本地不同JVM和跨节点JVM调用
ps:Fenced消息用来防止JobManager内组件在HA模式下的集群脑裂问题,思想fencing机制在选举时维护一个ID,过期ID无效化。

  • 调用消息(非Fenced):

LocalRpcInvocation: 本地RpcEndpoint 调用消息,同一个JVM内的调用
RemoteRpcInvocation: 远程RpcEndpoint 调用消息,包括本地不同JVM和跨节点JVM调用

  • 执行消息(消息体中带有Runnable或Callable对象,让Actor执行)

三、Flink通信组件

3.1 RpcGateway

Flink 的 RPC 协议通过 RpcGateway 来定义,主要定义通信行为(用于远程调用 RpcEndpoint 的某些方法),可以理解为对方的客服端代理。远程调用远端的Actor,则必须提供ip和端口号,这点在RpcGateway接口中也能看到。

3.2 RpcEndpoint

RpcEndpoint 是通信终端,提供 RPC 服务组件的生命周期管理(start、stop)。每个 RpcEndpoint 对应了一个路径(endpointId 和 actorSystem 共同确定),每个路径对应一个 Actor, 其实现了 RpcGateway 接口,其构造函数如下:

protected RpcEndpoint(final RpcService rpcService, final String endpointId)  
// 保存 rpcService 和 endpointId
this.rpcService = checkNotNull(rpcService, "rpcService");
this.endpointId = checkNotNull(endpointId, "endpointId");
// 通过 RpcService 启动 RpcServer
this.rpcServer = rpcService.startServer(this);
// 主线程执行器,所有调用在主线程中串行执行
this.mainThreadExecutor = new MainThreadExecutor(rpcServer,
							 this::validateRunsInMainThread); 

  构造的时候调用 rpcService.startServer()启动 RpcServer,进入可以接收处理请求的状态, 最后将 RpcServer 绑定到主线程上真正执行起来。

值得注意的是在 Flink 的设计中,对于同一个 Endpoint,所有的调用都运行在主线程,因此不会有并发问题,当启动 RpcEndpoint进行 Rpc 调用时,其会委托 RcpServer 进行处理。

3.3 RpcService与RpcServer

RpcService 和 RpcServer 是 RpcEndPoint 的成员变量。

(1) RpcService 是 Rpc 服务的接口,其主要作用如下:

  • 根据提供的RpcEndpoint来启动和停止RpcServer(Actor);
  • 根据提供的地址连接到(对方的)RpcServer,并返回一个RpcGateway;
  • 延迟/立刻调度Runnable、Callable;

  在 Flink 中实现类为 AkkaRpcService,是 Akka 的 ActorSystem 的封装,基本可以理解成 ActorSystem 的一个适配器。在 ClusterEntrypoint(JobMaster)和 TaskManagerRunner (TaskExecutor)启动的过程中初始化并启动。
  AkkaRpcService 中封装了 ActorSystem,并保存了 ActorRef 到 RpcEndpoint 的映射关系。 RpcService 跟 RpcGateway 类似,也提供了获取地址和端口的方法。
  RpcService会根据 RpcEndpoint 类型(FencedRpcEndpoint 或其他)来创建不同的 AkkaRpcActor(FencedAkkaRpcActor 或 AkkaRpcActor),并将 RpcEndpoint 和 AkkaRpcActor 对应的 ActorRef 保存起来,AkkaRpcActor 是底层 Akka 调用的实际接收者,RPC 的请求在客户端被封装成 RpcInvocation 对象,以 Akka消息的形式发送。

(2) RpcServer 负责接收响应远端 RPC 消息请求,自身的代理对象。有两个实现:

  • AkkaInvocationHandler
  • FencedAkkaInvocationHandler

RpcServer 的启动是通知底层的 AkkaRpcActor 切换为 START 状态,开始处理远程调用请求:

class AkkaInvocationHandler implements InvocationHandler, AkkaBasedEndpoint, RpcServer  @Override
	public void start() 
		rpcEndpoint.tell(ControlMessages.START, ActorRef.noSender());
	 

  远程RPC请求最终使用动态代理将所有的消息转发到 InvocationHandler,具体代码如下:

public <C extends RpcEndpoint & RpcGateway> RpcServer startServer(C rpcEndpoint) 
... ...
// 生成 RpcServer 对象,
//而后对该server的调用都会进入Handler的invoke方法处理,Handler实现了多个接口的方法

// 生成一个包含这些接口的代理,将调用转发到 InvocationHandler
@SuppressWarnings("unchecked")
	RpcServer server = (RpcServer) Proxy.newProxyInstance(
		classLoader,
		implementedRpcGateways.toArray(new Class<?> [implementedRpcGateways.size()]), 
		akkaInvocationHandler);

	return server;

3.4 AkkaRpcActor

AkkaRpcActor 是 Akka 的具体实现,主要负责处理如下类型消息:

  1. 本地 Rpc 调用 LocalRpcInvocation:
    会指派给 RpcEndpoint 进行处理,如果有响应结果,则将响应结果返还给 Sender(发消息的Actor)。
  2. RunAsync & CallAsync:
    这类消息带有可执行的代码,直接在 Actor 的线程中执行。
  3. 控制消息 ControlMessages:
    用来控制 Actor 行为,START 启动,STOP 停止,停止后收到的消息会丢弃掉。

四、PRC交互过程

具体流程如下:

首先强调几点,第一,RpcService是在ClusterEntrypoint(JobMaster)、TaskManagerRunner(TaskExecutor)启动过程中就被初始化和启动了的;第二,在RpcEndpoint初始化时传入参数RpcService并由其启动RpcServer进而启动整个RpcEndpoint(实际是自己给自己发消息使得内部封装的Actor收到了START消息)。这个启动过程在上图中也有体现。

  1. 启动过程见强调的两点,主要就是RpcService是对ActorSystem的底层封装。RpcEndpoint封装了RpcService和RpcServer,提供Actor执行的单一线程。而RpcServer是Endpoint处理RPC请求的代理(代理的各种本地、远端消息请求),其代理实现类承接了消息解析和对底层Actor的消息通知的任务。
  2. 在组件的Endpoint启动后,发送RPC请求的Endpoint由RpcService向对端的RpcServer发送请求。对端RpcServer并不会直接处理请求消息而是返回一个Gateway(自身的一个客户端)。发送端通过此Gateway向对端RpcServer请求远程调用方法。
  3. 而Gateway中会有一个InvocationHandler(也就是对方的代理),其中的invoke()会对调用请求进行分析、对应的封装和处理。比如,首先判断是否为PRC方法调用,是则调用invokeRpc(),此方法将消息封装为RPCInvocation消息(本地就为LocalRPCInvocation,远程则为RemoteRpcInvocation);然后判断方法调用是否需要等待结果,如果无需等待(void)则向Actor发送tell类型的消息,如果需要返回结果则发送ack类型消息。
  4. 消息代理后正式通过RpcEndpoint绑定的ActorRef发送给AkkaRpcActor,内部封装的Actor根据不同消息类型进行相应的处理(第二节所提到的4种消息类型)。

flink内核原理学习内存模型(代码片段)

Flink内核原理学习之内存模型文章目录Flink内核原理学习之内存模型一、JVM内存管理的缺点二、TaskManager内存模型三、内存数据结构四、网络传输中的内存管理4.1网络IO内存管理4.2反压机制Java、大数据开发学习要点(持续更新... 查看详情

flink之间的组件通信(代码片段)

...通信。而operator之间的数据传输是用netty。一句话总结,组件之间的传递用的akka,数据之间的网络传输用的是netty。flink通过akka进行的分布式通信的实现,在0.9版本使用。使用akka,所有远程过程调用现在都实现为异步消息。RPC框... 查看详情

flinkflink通讯组件rpc

1.概述本文是视频的笔记。尚硅谷2021最新Flink内核源码解析课程(从入门到精通)2.RPC通讯过程2.1RpcGatewayFlink的RPC协议通过RpcGateway来定义,主要定义通信行为;用于远程调用RpcEndpoint的某些方法ÿ 查看详情

flink更新中(代码片段)

...nkonYARN的部署模式,如下图所示:了解YARN的话,对上图的原理非常熟悉,实际Flink也实现了满足在YARN集群上运行的各个组件:FlinkYARNClient负责与YARNRM通信协商资源请求,FlinkJobManager和FlinkTaskManager分别申请到Container去运行各自的... 查看详情

一文搞懂rpc原理(代码片段)

RPC原理解析什么是RPCRPC(RemoteProcedureCallProtocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP/IP或UDP,为通信程序之间携带信... 查看详情

微服务学习rpc原理与gorpc(代码片段)

本文介绍了RPC的概念以及Go语言中标准库rpc的基本使用。什么是RPCRPC(RemoteProcedureCall),即远程过程调用。它允许像调用本地服务一样调用远程服务。RPC是一种服务器-客户端(Client/Server)模式,经典实现... 查看详情

区块链|智能合约ethereum源代码-以太坊rpc通信实例和原理代码分析(上)(代码片段)

上一节提到,以太坊在nodestart的时候启动了RPC服务,以太坊通过Rpc服务来实现以太坊相关接口的远程调用。这节我们用个实例来看看以太坊RPC是如何工作的,以及以太坊RPC的源码的实现一,RPC通信实例1,RPC启动命令:geth--rpcgo-et... 查看详情

flink原理学习窗口和时间(代码片段)

Flink原理学习之窗口和时间文章目录Flink原理学习之窗口和时间一、Flink的时间类型二、Watermark三、Flink窗口机制Java、大数据开发学习要点(持续更新中…)一、Flink的时间类型Flink的时间语义分为三种:EventTime:即... 查看详情

flink原理学习窗口和时间(代码片段)

Flink原理学习之窗口和时间文章目录Flink原理学习之窗口和时间一、Flink的时间类型二、Watermark三、Flink窗口机制Java、大数据开发学习要点(持续更新中…)一、Flink的时间类型Flink的时间语义分为三种:EventTime:即... 查看详情

hadoop相关重要源码学习

RPC通信原理解析通过源码深入理解以下hadoop的组件及重要流程,巩固学习;hdfs、yarn、mrdatanode和namenode如何通信?RM和NM如何通信?都是通过RPC通信协议(远程过程调用(RemoteProcedureCall))分为三个部分:... 查看详情

云小课|mrs基础原理之flink组件介绍(代码片段)

...擎。本文分享自华为云社区《【云小课】EI第44课MRS基础原理之Flink组件介绍》,作者:阅识风云。Flink是一个批处理和流处理结合的统一计算框架,其核心是一个提供了数据分发以及并行化计算的流数据处理引擎。它... 查看详情

vue2.0学习—vuex工作原理图(二十五)(代码片段)

【Vue2.0学习】—Vuex工作原理图(二十五)一、Vuex是什么?概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种... 查看详情

vue2.0学习—vuex工作原理图(二十五)(代码片段)

【Vue2.0学习】—Vuex工作原理图(二十五)一、Vuex是什么?概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种... 查看详情

day700.cluster组件:tomcat的集群通信原理-深入拆解tomcat&jetty(代码片段)

Cluster组件:Tomcat的集群通信原理Hi,我是阿昌,今天学习记录的是关于Cluster组件:Tomcat的集群通信原理的内容。为了支持水平扩展和高可用,Tomcat提供了集群部署的能力,但与此同时也带来了分布式系统... 查看详情

组件篇值rpc(上)(代码片段)

...Nacos消息队列事务消息延时消息Spring组件篇之RPC(上)01.RPC原理分析理解RPCRemoteProcedureCall远程过程调用基于网络表达语义和传达数据通信协议像调用本地方法调用远程服务扩展了算力服务治理的基础RPC作用屏蔽组包/解包屏蔽数据发... 查看详情

vue3组件通信学习笔记(代码片段)

一、父子组件之间通信父子组件之间如何进行通信呢?父组件传递给子组件:通过props属性;子组件传递给父组件:通过$emit触发事件;1.1父组件传递给子组件在开发中很常见的就是父子组件之间通信,比... 查看详情

vue学习系列--组件通信(代码片段)

通过上一章节的学习,我们已经知道父子组件之间可通过props进行通信,但在2.x之后的版本,props就变为单向的了:只能由父组件向子组件传值;但在实际的工作中,存在子组件向父组件传值的业务场景ÿ... 查看详情

rabbitmq学习:利用rabbitmq实现远程rpc调用(代码片段)

一、rabbitmq实现rpc调用的原理·rabbitmq实现rpc的原理是:客户端向一个队列中发送消息,并注册一个回调的队列用于接收服务端返回的消息,该消息需要声明一个叫做correaltionId的属性,该属性将是该次请求的唯一标识。服务端在... 查看详情