flink源码学习一

本文深入探讨Flink源码,重点关注Flink的RPC机制,包括Akka的使用、JobManager的ResourceManager、TaskManager的TaskExecutor,以及Flink的选举、监听和心跳机制。通过对关键组件和流程的分析,揭示了Flink如何实现高效稳定的分布式计算。
摘要由CSDN通过智能技术生成

Flink源码学习一

Flink RPC

​ Flink RPC底层基于Scala的网络编程库Akka实现。Akka具有如下特点:

1. 它是对并发模型进行了更高的抽象
2. 它是异步、非阻塞、高性能的事件驱动编程模型
3. 它是轻量级事件处理(1GB内存可容纳百万级别个Actor)

Akka的通信模型如下图:
在这里插入图片描述

关于AKka的理解可以从ActorSystem和Actor的角度理解,以下几个方面有助于我们理解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@master:9527/user/actor_name来进行定位
6. 如果一个Actor要和另外一个Actor进行通信,则必须先获取对方Actor的ActorRef对象,然后通过该对象发送消息即可
7. 通过tell发送异步消息,不接受响应,通过ask发送异步消息,得到Future返回,通过异步会到返回处理结果

使用Akka模拟实现Flink stadalone

代码如下:

JopManager:

package org.spiral.akka


import akka.actor.{
   Actor, ActorSystem, Props}
import com.typesafe.config.ConfigFactory

import scala.collection.mutable

/**
 * 注释: 集群主节点抽象
 * 1、receive 方法    接收其他 actor 发送过来的消息,然后进行模式匹配,进行消息处理,有可能返回消息
 * 2、preStart() 方法   对象在构建成功之后,就会触发执行 preStart
 * 3、postStop 方法    在对象销毁之前,会执行一次
 * -
 * 必须了解的知识:
 * 1、伴生类 class A 和 伴生对象 object A(定义的方法,都是静态方法)
 * 2、关于 scala 中定义的一个类的构造方法:
 *   构造器: 类名后面的括号
 *   代码实现: {} 中的一切能执行的代码
 *     变量的初始化
 *     代码块
 *     静态代码块
 *     不能执行的代码: 定义的方法(未调用, 内部类)
 *
 * @author spiral
 * @since : 2021/7/6 1:26
 *
 */

class MyJobManager(var hostName: String, var port: Int) extends Actor {
   

  var id2TaskManagerInfo = new mutable.HashMap[String, TaskManagerInfo]()

  var taskMangerInfos = new mutable.HashSet[TaskManagerInfo]()


  override def preStart(): Unit = {
   
    import scala.concurrent.duration._
    import context.dispatcher
    context.system.scheduler.schedule(0 millis, 5000 millis, self, CheckTimeOut)
  }

  override def receive: Receive = {
   
    case RegisterTaskManager(nodeManagerId, memory, cpu) => {
   
      val nodeManagerInfo = new TaskManagerInfo(nodeManagerId, memory, cpu)
      println(s"节点 ${nodeManagerId}上线")

      id2TaskManagerInfo.put(nodeManagerId, nodeManagerInfo)
      taskMangerInfos += nodeManagerInfo

      sender() ! RegisteredTaskManager(hostName + ":" + port)
    }
    case Heartbeat(nodeManagerId) => {
   
      val concurrentTime = System.currentTimeMillis()
      val nodeManagerInfo = id2TaskManagerInfo(nodeManagerId)
      nodeManagerInfo.lastHeartBeatTime = concurrentTime

      id2TaskManagerInfo(nodeManagerId) = nodeManagerInfo
      taskMangerInfos += nodeManagerInfo

      sender() !Heartbeat(hostName)
    }
    case CheckTimeOut => {
   
      val currentTime = System.currentTimeMillis()
      taskMangerInfos.filter(nm =>{
   
        val heartbeatTimeout= 15000
        val bool = currentTime - nm.lastHeartBeatTime > heartbeatTimeout
        if (bool) {
   
          println(s"节点${nm.taskmanagerid} 下线")
        }
        bool
      }).foreach(deadNodeManager=>{
   
        taskMangerInfos -= deadNodeManager
        id2TaskManagerInfo.remove(deadNodeManager.taskmanagerid)
      })

      println("当期注册成功的节点数"+ taskMangerInfos.size+"\t 分别是:"+ taskMangerInfos.map(x => x.toString)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值