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 ...
随机推荐
- 系统性能--CPU
对于cpu,目前比较关心的是cpu的利用率还有cpu的load,或者还有cpu运行队列. cpu利用率 cpu利用率分为sys,us.分别为操作系统和用户进程所占用的cpu利用率.sys的占用,一般是 ...
- FreeRTOS的内存管理
FreeRTOS提供了几个内存堆管理方案,有复杂的也有简单的.其中最简单的管理策略也能满足很多应用的要求,比如对安全要求高的应用,这些应用根本不允许动态内存分配的. FreeRTOS也允许你自己实现内 ...
- 团队博客-第六周:Alpha阶段项目复审(只会嘤嘤嘤队)
小组名 题目 优点 缺点 排名 小谷围驻广东某工业719电竞大队 广工生活社区 功能多样,设计完整,实用,界面美观 界面风格不够统一,当前时间系统尚未发布 1 大猪蹄子队 四六级背单词游戏 界面十分美 ...
- unity 简单通用游戏模式设计
好吧好吧,又谈到这个问题了,其实早就想写这个博客了,犹豫了好久.在设计游戏的时候我本人是很排斥什么游戏架构设计,mvc什么的,我只想马上动手就把自己的游戏玩法最快的用代码敲出来,还不会出无法挽回的错误 ...
- JavaScript在IE和Firefox的不兼容问题解决方法总结
1.兼容Firefox的 outerHTML,Firefox中没有outerHtml的方法. if (window.HTMLElement) { HTMLElement.prototype.__def ...
- 《JavaScript面向对象编程指南》读书笔记②
概述 <JavaScript面向对象编程指南>读书笔记① 这里只记录一下我看JavaScript面向对象编程指南记录下的一些东西.那些简单的知识我没有记录,我只记录几个容易遗漏的或者精彩的 ...
- API接口设计:防参数篡改+防二次请求
API接口由于需要供第三方服务调用,所以必须暴露到外网,并提供了具体请求地址和请求参数 为了防止被第别有用心之人获取到真实请求参数后再次发起请求获取信息,需要采取很多安全机制 1.首先: 需要采用ht ...
- Facebook的一些基本操作(网页版)
前期准备 1,注册一次Facebook账号,新建一个应用取到应用id 2,引进Facebook的SDK到页面中: 在js中引进以下代码,初始化 // facebook window.fbAsyncIn ...
- ubuntu解压rar文件
一般通过默认安装的ubuntu是不能解压rar文件的,只有在安装了rar解压工具之后,才可以解压.其实在ubuntu下安装rar解压工具是非常简 单的,只需要两个步骤就可以迅速搞定. ubuntu 下 ...
- 14-使用glusterfs做持久化存储
使用glusterfs做持久化存储 我们复用kubernetes的三台主机做glusterfs存储. 以下步骤参考自:https://www.xf80.com/2017/04/21/kubernete ...