flink-源码探索-RPC-分析

背景介绍:

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

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

1、 Flink RPC 网络通信框架。

2、 Flink RPC 案例。

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

一、 Flink RPC 网络通信框架。

flink-源码探索-RPC-分析_第1张图片

flink的rpc主要组件如下图:

flink-源码探索-RPC-分析_第2张图片

flink-源码探索-RPC-分析_第3张图片

 flink-源码探索-RPC-分析_第4张图片

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

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

 flink-源码探索-RPC-分析_第5张图片

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 返回,通过异步回到返回处理结果

简单总结:

flink-源码探索-RPC-分析_第6张图片

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 添加如下几个依赖:


    org.apache.flink
    flink-core
    ${flink.version}



    org.apache.flink
    flink-runtime_2.12
    ${flink.version}

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())
    } 

}

结果如下:

flink-源码探索-RPC-分析_第7张图片

 

 

你可能感兴趣的:(flink探索笔记,技术分享,flink,rpc,p2p)