Spark start-all>>

"""Master启动流程"""

Master类
class Master(
host: String,
port: Int,
webUiPort: Int,
val securityMgr: SecurityManager,
val conf: SparkConf) extends Actor with ActorLogReceive with Logging with LeaderElectable Master端
def main(){
val (actorSystem, _, _, _) = startSystemAndActor(args.host, args.port, args.webUiPort, conf)
actorSystem.awaitTermination()
} Master端
def startSystemAndActor(System, Int, Int, Option[Int]) = {
//调用AkkaUtils创建ActorSystem
val (actorSystem, boundPort) = AkkaUtils.createActorSystem(systemName, host, port, conf = conf,
securityManager = securityMgr)
//创建属于Master的actor, 在创建actor的同时, 会使用classOf[Master]初始化Master
val actor = actorSystem.actorOf(Props(classOf[Master], host, boundPort, webUiPort, securityMgr, conf), actorName)
} Master端
"""初始化Master时由于Master继承了 trait Actor 重写了preStart方法,
Actor的初始化会启动preStart方法 因此找到Master的 override def preStart()
preStart属于生命周期方法, 在构造器之后, receiver之前"""
override def preStart() {
// 启动一个定时器, 定时检查超时的Worker, WORKER_TIMEOUT:每六十秒检查一次,
// self:先对着自己来一下(检查)试试
context.system.scheduler.schedule(0 millis, WORKER_TIMEOUT millis, self, CheckForWorkerTimeOut)
// 调用 timeOutDeadWorkers() 方法,
override def receiveWithLogging = {
case CheckForWorkerTimeOut => {
timeOutDeadWorkers()
}
} // 用来检查并移除所有超时的workers
def timeOutDeadWorkers(){
// 事实上是移除了一个存有WorkInfo的HashSet[WrokInfo]中的对象
val toRemove = workers.filter(_.lastHeartbeat < currentTime - WORKER_TIMEOUT_MS).toArray
for (worker <- toRemove) {
if (worker.state != WorkerState.DEAD) {
removeWorker(worker)
}
}
} def removeWorker(worker: WorkerInfo){
// 删除内存里的workInfo
idToWorker -= worker.id
addressToWorker -= worker.endpoint.address
}
} """之后执行receive方法(1.3版本), 在后来的1.6版本中叫 def receive: PartialFunction[Any, Unit]"""
Master端
override def receiveWithLogging () {}
会不断的接收actor发送过来的请求 """Worker启动流程""" Worker类
class Worker(
host: String,
port: Int,
webUiPort: Int,
cores: Int,
memory: Int,
masterAkkaUrls: Array[String],
actorSystemName: String,
actorName: String,
workDirPath: String = null,
val conf: SparkConf,
val securityMgr: SecurityManager)
extends Actor def preStart() => {
registerWithMaster()
} // 向Master注册的方法
def registerWithMaster() {
// 向所有的Master注册Worker
tryRegisterAllMasters() // 其中内容
def tryRegisterAllMasters()=>{
// 通过Master的Url获取Master的actor
val actor = context.actorSelection(masterAkkaUrl)
// 向Master发送注册信息
actor ! RegisterWorker(workerId, host, port, cores, memory, webUi.boundPort, publicAddress)
}
} Master端
// 接收Worker发送的注册信息
override def receiveWithLogging = {
case RegisterWorker(id, workerHost, workerPort, cores, memory, workerUiPort, publicAddress) =>{
// 判断是否是StandBy状态, doNothing
idToWorker.contains(id), 已经注册过, doNothing 正常情况下(Active状态, 且没有注册过):{
// 把发送来的 WorkerInfo 添加到 Master的 WorkerInfo中
val worker = new WorkerInfo(id, workerHost, workerPort, cores, memory, sender, workerUiPort, publicAddress)
}
// 如果将Worker Info存入内存成功, 则调用持久化引擎, 将信息存入磁盘中,
// 目的是防止数据丢失. 如果Master宕机, 内存中会丢失数据,
// 切换状态(Standby和Active)后, 需要切换的节点拿不到WorkerInfo, Worker会再次注册, 非常消耗资源, 存在磁盘则可以直接去磁盘拿取数据不需要重新注册
if (registerWorker(worker)) {
persistenceEngine.addWorker(worker)
sender ! RegisteredWorker(masterUrl, masterWebUiUrl)
schedule()
} // 向worker响应注册成功信息
sender ! RegisteredWorker(masterUrl, masterWebUiUrl)
// 开始调度资源, 调度资源不仅仅是集群启动的时候调动资源, 运行Job的时候也会调度资源, 其有两种方式 一种是尽量分散, 一种是尽量集中
schedule()
}
} Worker端
// 接收注册成功的信息, 其实是将 Active Master 的Url和rWebUiUrl传回并更新, 之后向他发送心跳~
def receiveWithLogging() = {
case RegisteredWorker(masterUrl, masterWebUiUrl) =>{
//更新MasterUrl
changeMaster(masterUrl, masterWebUiUrl)
//向Master发送心跳信息, HEARTBEAT_MILLIS =15秒, 每十五秒发送一次心跳信息, 发送逻辑为 SendHeartbeat
context.system.scheduler.schedule(0 millis, HEARTBEAT_MILLIS millis, self, SendHeartbeat)
} //向Master发送心跳信息, 实际上是将自己的WorkerId发送给Master
case SendHeartbeat =>
if (connected) { master ! Heartbeat(workerId) }
} Master端
def receiveWithLogging() = {
case Heartbeat(workerId) => {
//正常情况下, 更新上次心跳时间
workerInfo.lastHeartbeat = System.currentTimeMillis()
//启动完成
}
}

  

Spark-源码-Spark-StartAll Master Worler启动流程的更多相关文章

  1. Flink 源码解析 —— Standalone Session Cluster 启动流程深度分析之 Job Manager 启动

    Job Manager 启动 https://t.zsxq.com/AurR3rN 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Mac ...

  2. Flink 源码解析 —— Standalone session 模式启动流程

    Standalone session 模式启动流程 https://t.zsxq.com/EemAEIi 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0 ...

  3. Flink 源码解析 —— Standalone Session Cluster 启动流程深度分析之 Task Manager 启动

    Task Manager 启动 https://t.zsxq.com/qjEUFau 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Ma ...

  4. Caddy源码阅读(二)启动流程与 Event 事件通知

    Caddy源码阅读(二)启动流程与 Event 事件通知 Preface Caddy 是 Go 语言构建的轻量配置化服务器.https://github.com/caddyserver/caddy C ...

  5. DolphinScheduler 源码剖析之 Master 容错处理流程

    点击上方蓝字关注 Apache DolphinScheduler Apache DolphinScheduler(incubating),简称"DS", 中文名 "海豚调 ...

  6. 头秃了,二十三张图带你从源码了解Spring Boot 的启动流程~

    持续原创输出,点击上方蓝字关注我 目录 前言 源码版本 从哪入手? 源码如何切分? 如何创建SpringApplication? 设置应用类型 设置初始化器(Initializer) 设置监听器(Li ...

  7. Tomcat8源码笔记(九)组件StandardContext启动流程--未完待续

    StandardContext代表的是webapps下项目,一个项目就是一个StandardContext,作为Tomcat组件的一部分,就会实现Lifecycle接口,被Tomcat管理着生命周期, ...

  8. Spark源码分析之Sort-Based Shuffle读写流程

    一 .概述 我们知道Spark Shuffle机制总共有三种: 1.未优化的Hash Shuffle:每一个ShuffleMapTask都会为每一个ReducerTask创建一个单独的文件,总的文件数 ...

  9. Apache DolphinScheduler 源码剖析之 Worker 容错处理流程

    今天给大家带来的分享是 Apache DolphinScheduler 源码剖析之 Worker 容错处理流程 DolphinScheduler源码剖析之Worker容错处理流程 Worker容错流程 ...

随机推荐

  1. Android应用开发基础之七:广播与服务(一)

    广播 广播的概念 现实:电台通过发送广播发布消息,买个收音机,就能收听 Android:系统在产生某个事件时发送广播,应用程序使用广播接收者接收这个广播,就知道系统产生了什么事件. Android系统 ...

  2. MyISAM引擎表出现“Error 'Incorrect key file for table”

    mysql主从复制中的从库突然出现了警报,sql_thread停止了,show slave status\G;查看 mysql> show slave status\G ; . row **** ...

  3. 笨办法学Python(四十)

    习题 40: 字典, 可爱的字典 接下来我要教你另外一种让你伤脑筋的容器型数据结构,因为一旦你学会这种容器,你将拥有超酷的能力.这是最有用的容器:字典(dictionary). Python 将这种数 ...

  4. numpy cheat sheet

    numpy cheat sheet https://files.cnblogs.com/files/lion-zheng/Numpy_Python_Cheat_Sheet.pdf

  5. May 25th 2017 Week 21st Thursday

    Follow your heart, but take your brain with you. 跟随你的内心,但是请别失去理智. I was ever told that we should fol ...

  6. 如何用ABAP代码读取CDS view association的数据

    我有如下一个CDS view, 这个view的数据来自CRMD_ORDERADM_H, 定义了一个名称为_statushelp的association, 指向了另一个CDS view Z_C_Stat ...

  7. python 提取字符串中的数字组成新的字符串

    方法一 # 有一个字符串text = "aAsmr3idd4bgs7Dlsf9eAF" # 请将text字符串中的数字取出,并输出成一个新的字符串 import re text = ...

  8. (String)、toString()与String.valueOf()的区别

    (String).Object.toString()正常情况下跟String.valueOf()没有区别. 但当Object是null的时候.toString会抛出异常.valueOf返回" ...

  9. 关于表空间、Schema和用户

    数据库这个柜子 解释数据库.表空间.数据文件.表.数据的最好办法就是想象一个装满东西的柜子. 从物理方面来讲:数据库是柜子,柜中的抽屉是表空间,抽屉中的文件夹是数据文件,文件夹中的纸是表,写在纸上的信 ...

  10. OC 枚举

    void test() { // 定义一种枚举类型 enum Season {spring, summer, autumn, winter}; // 定义一个枚举变量s enum Season s = ...