flink-源码探索-RPC-分析

背景介绍:

对flink整个流程进行分析,首先第一步需要了解每个组件之前的通讯方式,以及调用的流程,这样就可以对后面研究的代码,主要分析flink1.14.2比较新的版本。

主要分析大体如以下的内容:

1、 Flink RPC 网络通信框架。

2、 Flink RPC 案例。

3、 Flink基础组件的RPC实现。

一、 Flink RPC 网络通信框架。

flink的rpc主要组件如下图:

 

 从上面可以看出来Flink PRC是基于Akka实现的。那么Akka的工作机制又是什么呢?

关于akka的工作机制原理如下:

 

1、ActorSystem 是管理 Actor 生命周期的组件,Actor 是负责进行通信的组件

2、每个 Actor 都有一个 MailBox,别的 Actor 发送给它的消息都首先储存在 MailBox 中,通过这种方式可以实现异步通信。

3、每个 Actor 是单线程的处理方式,不断的从 MailBox 拉取消息执行处理,所以对于 Actor 的消息处理,不适合调用会阻塞的处理方法。

4、Actor 可以改变他自身的状态,可以接收消息,也可以发送消息,还可以生成新的 Actor(谁生的谁养)

5、每一个 ActorSystem 和 Actor 都在启动的时候会给定一个 name,如果要从 ActorSystem 中,获取一个 Actor,则通过以下的方式来进行 Actor 的获取:akka.tcp://actorsystem_name@bigdata02:9527/user/actor_name 来进行定位

6、如果一个 Actor 要和另外一个 Actor 进行通信,则必须先获取对方 Actor 的 ActorRef 对象,然后通过该对象发送消息即可。actorRef = actorSystem.actorOf("akka.tcp://actorsystem_name@bigdata02:9527/user/actor_name")// 获取和对方 actor 进行通信的一个 actorRef 对象,类似于一个本地调用,但事实上,actorRef 和 对方actor 的通信细节被封装了。actorRef = actorSystem.actorOf("schema://actorsystem_name@hostname:port/user/actor_name")actorRef.getNow()

7、通过 tell 发送异步消息,不接收响应,通过 ask 发送异步消息,得到 Future 返回,通过异步回到返回处理结果

简单总结:

1、RpcGateway 路由,RPC 的老祖宗,各种其他 RPC 服务组件,都是 RpcGateWay 的子类,类似于 Hadoop 中的通信协议 Protocol

2、RpcEndpoint 业务逻辑载体,对应的 Actor 的封装

3、RpcService 对应 ActorSystem 的封装,类似于 Spark 中的 RpcEnv

4、RpcServer RpcService(ActorSystem)和 RpcEndpoint(Actor)之间的粘合层

 

最后总结:RpcEndpoint 下面有四个比较重要的子类

1、TaskExecutor 集群中从节点中最重要的角色,负责资源管理

2、Dispatcher 主节点中的一个工作角色,负责 job 调度执行

3、JobMaster 应用程序中的主控程序,类似于 Spark 中的 Driver 的作用,或者 MapReduce 中的 MRAppMaster

4、ResourceManager 集群中的主节点 JobManager 中的负责资源管理的角色,和 TaskExecutor 一起构成资源管理的主从架构

二、RPC案例demo

pom.xml 添加如下几个依赖:

<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-core</artifactId>
    <version>${flink.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.flink/flink-runtime -->
<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-runtime_2.12</artifactId>
    <version>${flink.version}</version>
</dependency>

java code如下:

package com.mazh.flink.rpc.service;

import akka.actor.ActorSystem;
import com.mazh.flink.rpc.demo01.HelloRpcEndpoint;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.runtime.akka.AkkaUtils;
import org.apache.flink.runtime.rpc.RpcService;
import org.apache.flink.runtime.rpc.akka.AkkaRpcService;
import org.apache.flink.runtime.rpc.akka.AkkaRpcServiceConfiguration;

public class MyService {
    public static void main(String[] args) {

//        ActorSystem actorSystem = AkkaUtils.createDefaultActorSystem();
        Configuration configuration = new Configuration();
        ActorSystem actorSystem = AkkaUtils.createActorSystem(configuration, "localhoust", 9999);
        // 创建 RpcService, 基于 AKKA 的实现
        RpcService rpcService = new AkkaRpcService(actorSystem, AkkaRpcServiceConfiguration.defaultConfiguration());
        HelloRpcEndpoint helloRpcEndpoint = new HelloRpcEndpoint(rpcService);
        String address = helloRpcEndpoint.getAddress();
        System.out.println(address);
        helloRpcEndpoint.start();
    }
}
 


import org.apache.flink.runtime.rpc.RpcEndpoint;
import org.apache.flink.runtime.rpc.RpcService;

/**
 * Author:
 * Description:
 */
public class HelloRpcEndpoint extends RpcEndpoint implements HelloGateway {

    public HelloRpcEndpoint(RpcService rpcService) {
        super(rpcService);
    }

    @Override
    public String hello() {
        return "Hello Flink RPC";
    }
}

package com.mazh.flink.rpc.service;

import akka.actor.ActorSystem;
import com.mazh.flink.rpc.demo01.HelloGateway;
import org.apache.flink.runtime.akka.AkkaUtils;
import org.apache.flink.runtime.rpc.RpcService;
import org.apache.flink.runtime.rpc.akka.AkkaRpcService;
import org.apache.flink.runtime.rpc.akka.AkkaRpcServiceConfiguration;

import java.util.concurrent.ExecutionException;

public class MyClient {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ActorSystem actorSystem = AkkaUtils.createDefaultActorSystem();
        RpcService akkaRpcService = new AkkaRpcService(actorSystem, AkkaRpcServiceConfiguration.defaultConfiguration());
        HelloGateway getNowGateway = akkaRpcService.connect("akka.tcp://flink@localhoust:9999/user/rpc/e18c9493-e5bc-4e9f-a6df-ccb71d7c755b", HelloGateway.class).get();
        System.out.println(getNowGateway.hello())
    } 

}

结果如下:

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值