Spark中master与worker的进程RPC通信实现
1.构建master的actor
package SparkRPC
import akka.actor.{Actor, ActorSystem, Props}
import com.typesafe.config.ConfigFactory
import scala.collection.mutable
/**
  * Created by hqs on 2018/1/24.
  * 1.启动master,启动worker
  * 2.worker启动后连接master,发送注册消息(封装起来)
  * 3.master受到注册消息并保存,返回注册成功消息给worker
  * 4.worker启动一个定时任务,发送心跳给master(先发送给自己,在发送给master)
  * 5.master接收心跳消息,更新保存的心跳信息
  *
  * 6.master主动启动一个定时任务,检查心跳时间是否超过设定值,若超过,则删除worker的注册信息。
  */
class Master extends Actor {
private val workerMp: mutable.HashMap[String, WorkerInfo] = new mutable.HashMap[String, WorkerInfo]()
override def preStart(): Unit = {
    //启动定时任务去检查是否有死去的worker
    import scala.concurrent.duration._
    import context.dispatcher
    context.system.scheduler.schedule(0 second, 15 second, self, CheckWorker)
  }
override def receive: Receive = {
    case "start" => println("master start...")
    //接收并注册,返回成功消息。
    case Register2Master(workerId, cores, memory) => {
      workerMp(workerId) = new WorkerInfo(cores, memory)
      println(s"add a worker,workerId = ${workerId}")
      println(s"now total workers = ${workerMp.size}")
      sender() ! RegisSuccess
    }
    //接收心跳,更新信息
    case HeartBeat(workerId) => {
      if (workerMp.contains(workerId)) {
        workerMp(workerId).lastloginTime = System.currentTimeMillis()
      }
    }
    case CheckWorker => {
      //过滤出已经超时的worker,大于两个心跳认为超时。
      val deadWorkers = workerMp.filter({
        mp => {
          System.currentTimeMillis() - mp._2.lastloginTime > 20 * 1000
        }
      })
      //用一个map来减去另外一个map
      workerMp --= deadWorkers.map(mp => mp._1)
      println(s"now total workers = ${workerMp.size}")
    }
  }
}
object Master {
val MASTER_ACS_NAME = "master_acs_name"
  val MASTER_AC_NAME = "master_ac_name"
def main(args: Array[String]): Unit = {
if (args.length != 2) {
      println("Master  <masterIp,masterPort>")
      sys.exit()
    }
val Array(masterIp, masterPort) = args
    val str =
      s"""
         |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname = "${masterIp}"
         |akka.remote.netty.tcp.port = "${masterPort}"
      """.stripMargin
    val conf = ConfigFactory.parseString(str)
    val acs: ActorSystem = ActorSystem.create(MASTER_ACS_NAME, conf)
    val masterRef = acs.actorOf(Props(new Master), MASTER_AC_NAME)
masterRef ! "start"
}
}
2.构建worker的actor
package SparkRPC
import java.util.UUID
import akka.actor.{Actor, ActorSelection, ActorSystem, Props}
import com.typesafe.config.ConfigFactory
/**
  * Created by hqs on 2018/1/24.
  */
class Worker(val masterIp:String,val masterPort:Int,val cores:Int,val memory:Int) extends  Actor{
  val workerId = UUID.randomUUID().toString
  var masSele: ActorSelection = null
  //注册worker信息
  override def preStart(): Unit = {
    //取得master的路径
    val path = s"akka.tcp://${Master.MASTER_ACS_NAME}@${masterIp}:${masterPort}/user/${Master.MASTER_AC_NAME}"
    masSele = context.actorSelection(path)
    masSele ! Register2Master(workerId,cores,memory)
}
override def receive: Receive = {
    case "start" => println("worker starting")
      //发送定时心跳信息
    case RegisSuccess => {
      println("success start scheduler")
      /**
        * initialDelay: FiniteDuration,   延迟时间   延迟启动定时任务的时间
        * interval:     FiniteDuration,    间隔时间   每隔多长时间
        * receiver:     ActorRef,         信息发给谁   接收方
        * message:      Any               发送的信息   封装成case  class
        */
      //导入时间单位,启动定时任务。
      import scala.concurrent.duration._
      import context.dispatcher
      context.system.scheduler.schedule(0 second,10 second,self,SendHeartBeat)
    }
    case SendHeartBeat => {
      masSele ! HeartBeat(workerId)
      println("worker 向 master 发送心跳信息...")
    }
  }
}
object Worker{
val WORKER_ACS_NAME = "worker_acs_name"
  val WORKER_AC_NAME = "worker_ac_name"
  def main(args: Array[String]): Unit = {
if(args.length != 6){
      println("Worker <masterIp,masterPort,workerIp,workerPort,cores,memory>")
      sys.exit()
    }
    val Array(masterIp,masterPort,workerIp,workerPort,cores,memory) = args
val str =
        s"""
          |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
          |akka.remote.netty.tcp.hostname = "${workerIp}"
          |akka.remote.netty.tcp.port = "${workerPort}"
        """.stripMargin
    val conf = ConfigFactory.parseString(str)
    val acs = ActorSystem.create(WORKER_ACS_NAME,conf)
    val scRef = acs.actorOf(Props(new Worker(masterIp,masterPort.toInt,cores.toInt,memory.toInt)),WORKER_AC_NAME)
scRef ! "start"
  }
}
3.master与worker的消息传递封装
package SparkRPC
/**
  * Created by hqs on 2018/1/27.
  */
class Message {
}
//worker发送注册消息
case class Register2Master(workerId:String,cores:Int,memory:Int)
//master返回注册成功的消息
case object RegisSuccess
//发送心跳给自己
case object SendHeartBeat
//发送心跳给master
case class HeartBeat(workerId:String)
//master定时检查worker存活状态
case object CheckWorker
4.总结:master与worker依赖于akka的actor来实现通信。会产生定时心跳任务,检查超时的worker。
Spark中master与worker的进程RPC通信实现的更多相关文章
- 【原】Spark中Master源码分析(二)
		继续上一篇的内容.上一篇的内容为: Spark中Master源码分析(一) http://www.cnblogs.com/yourarebest/p/5312965.html 4.receive方法, ... 
- <spark> error:启动spark后查看进程,进程中master和worker进程冲突
		启动hadoop再启动spark后jps,发现master进程和worker进程同时存在,调试了半天配置文件. 测试发现,当我关闭hadoop后 worker进程还是存在, 但是,当我再关闭spark ... 
- 【原】Spark中Master源码分析(一)
		Master作为集群的Manager,对于集群的健壮运行发挥着十分重要的作用.下面,我们一起了解一下Master是听从Client(Leader)的号召,如何管理好Worker的吧. 1.家当(静态属 ... 
- Spark技术内幕:Client,Master和Worker 通信源码解析
		http://blog.csdn.net/anzhsoft/article/details/30802603 Spark的Cluster Manager可以有几种部署模式: Standlone Mes ... 
- Spark技术内幕:Client,Master和Worker 通信源代码解析
		Spark的Cluster Manager能够有几种部署模式: Standlone Mesos YARN EC2 Local 在向集群提交计算任务后,系统的运算模型就是Driver Program定义 ... 
- 【原】 Spark中Worker源码分析(一)
		Worker作为对于Spark集群的健壮运行起着举足轻重的作用,作为Master的奴隶,每15s向Master告诉自己还活着,一旦主人(Master>有了任务(Application),立马交给 ... 
- 【原】 Spark中Worker源码分析(二)
		继续前一篇的内容.前一篇内容为: Spark中Worker源码分析(一)http://www.cnblogs.com/yourarebest/p/5300202.html 4.receive方法, r ... 
- Spark分析之Master、Worker以及Application三者之间如何建立连接
		Master.preStart(){ webUi.bind() context.system.scheduler.schedule( millis, WORKER_TIMEOUT millis, se ... 
- Spark 中的 RPC 的几个类
		Spark 中 RPC 部分的涉及了几个类,有点晕,在此记录一下 1. RpcEndpoint: RPC的一个端点.给定了相应消息的触发函数.保证 `onStart`, `receive` and ... 
随机推荐
- bgfx入门练习1——切换图形API驱动模式DX与OpenGL
			翻了下上次编译bgfx是去年2月份的事了,最近正好想试试DX,OpenGL双驱动,看Urho3D和Klayge光封装就头痛,人又懒,写OpenGL时也基本glfw,于是想到bgfx,不如再试试. 发现 ... 
- 1.2万事开头hello world+交互+getpass、sys模块初识
			1.python的hello world: ①运行cmd-输入python-输入print (“hello world!”) ②创造.py的文本helloworld.py(后缀是为了告诉其他人)-输入 ... 
- No趴笨小分队
			这星期完成了小组的取名这一项重大的活动. 正所谓“名字是一个好开头”,取这个名义有以下的意义: 希望之后的学习以及工作能一帆风顺: 祝福各位小组成员之后的路能顺顺利利: 希望能在组员磨合的过程中可以愉 ... 
- Python json和pickle模块
			用于序列化的两个模块 json,用于字符串 和 python数据类型间进行转换 pickle,用于python特有的类型 和 python的数据类型间进行转换 Json模块提供了四个功能:dumps. ... 
- [转]kaldi上的深度神经网络
			转:http://blog.csdn.net/wbgxx333/article/details/41019453 深度神经网络已经是语音识别领域最热的话题了.从2010年开始,许多关于深度神经网络的文 ... 
- 2月第3周业务风控关注|上海网信办复测23个被约谈APP 涉及1号店、小红书等
			易盾业务风控周报每周呈报值得关注的安全技术和事件,包括但不限于内容安全.移动安全.业务安全和网络安全,帮助企业提高警惕,规避这些似小实大.影响业务健康发展的安全风险. 1.上海网信办复测23个被约谈A ... 
- Thinking in Java from Chapter 10
			From Thinking in Java 4th Edition 内部类 public class Parcel1 { class Contents { private int i = 11; pu ... 
- Two strings 的另一种解法
			Two strings 的另一种解法 论文中的解法是离线插入 \(O(\log n)\) 询问 \(O(\log n)\) 的,不过我发现有一种离线插入 \(O(1)\) 询问 \(O(\log n) ... 
- struts2框架学习笔记5:OGNL表达式
			OGNL取值范围分两部分,root.Context两部分 可以放置任何对象作为ROOT,CONTEXT中必须是Map键值对 示例: 准备工作: public void fun1() throws Ex ... 
- Liferay7 BPM门户开发之20: 理解Asset Framework
			Asset框架用于将您开发的门户内容添加Liferay的核心系统功能.打个比方,你开发了一个事件TodoList管理的插件,在列表显示的时候,你可以集成Asset框架,让你的自定义内容支持Tag标签. ... 
