DStreamGraph有点像简洁版的DAG scheduler,负责根据某个时间间隔生成一序列JobSet,以及按照依赖关系序列化。这个类的inputStream和outputStream是最重要的属性。spark stream将动态的输入流与对流的处理通过一个shuffle来连接。前面的(shuffle map)是input stream,其实是DStream的子类,它们负责将收集的数据以block的方式存到spark memory中;而output stream,是另外的一系类DStream,负责将数据从spark memory读取出来,分解成spark core中的RDD,然后再做数据处理。





final private[streaming] class DStreamGraph extends Serializable with Logging {

private val inputStreams = new ArrayBuffer[InputDStream[_]]()
private val outputStreams = new ArrayBuffer[DStream[_]]()

var rememberDuration: Duration = null
var checkpointInProgress = false

var zeroTime: Time = null
var startTime: Time = null
var batchDuration: Duration = null


def addInputStream(inputStream: InputDStream[_]) {
this.synchronized {
inputStream.setGraph(this)
inputStreams += inputStream
}
}

def addOutputStream(outputStream: DStream[_]) {
this.synchronized {
outputStream.setGraph(this)
outputStreams += outputStream
}
}

def getInputStreams() = this.synchronized { inputStreams.toArray }

def getOutputStreams() = this.synchronized { outputStreams.toArray }

def getReceiverInputStreams() = this.synchronized {
inputStreams.filter(_.isInstanceOf[ReceiverInputDStream[_]])
.map(_.asInstanceOf[ReceiverInputDStream[_]])
.toArray
}


def generateJobs(time: Time): Seq[Job] = {
logDebug("Generating jobs for time " + time)
val jobs = this.synchronized {
outputStreams.flatMap(outputStream => outputStream.generateJob(time))
}
logDebug("Generated " + jobs.length + " jobs for time " + time)
jobs
}


@throws(classOf[IOException])
private def writeObject(oos: ObjectOutputStream): Unit = Utils.tryOrIOException {
logDebug("DStreamGraph.writeObject used")
this.synchronized {
checkpointInProgress = true
logDebug("Enabled checkpoint mode")
oos.defaultWriteObject()
checkpointInProgress = false
logDebug("Disabled checkpoint mode")
}
}

@throws(classOf[IOException])
private def readObject(ois: ObjectInputStream): Unit = Utils.tryOrIOException {
logDebug("DStreamGraph.readObject used")
this.synchronized {
checkpointInProgress = true
ois.defaultReadObject()
checkpointInProgress = false
}
}

JobScheduler负责产生jobs
/**
* This class schedules jobs to be run on Spark. It uses the JobGenerator to generate
* the jobs and runs them using a thread pool.
*/
private[streaming]
class JobScheduler(val ssc: StreamingContext) extends Logging {

private val jobSets = new ConcurrentHashMap[Time, JobSet]
private val numConcurrentJobs = ssc.conf.getInt("spark.streaming.concurrentJobs", 1)
private val jobExecutor = Executors.newFixedThreadPool(numConcurrentJobs)
private val jobGenerator = new JobGenerator(this)
val clock = jobGenerator.clock
val listenerBus = new StreamingListenerBus()

// These two are created only when scheduler starts.
// eventActor not being null means the scheduler has been started and not stopped
var receiverTracker: ReceiverTracker = null
private var eventActor: ActorRef = null

def start(): Unit = synchronized {
if (eventActor != null) return // scheduler has already been started

logDebug("Starting JobScheduler")
eventActor = ssc.env.actorSystem.actorOf(Props(new Actor {
def receive = {
case event: JobSchedulerEvent => processEvent(event)
}
}), "JobScheduler")

listenerBus.start()
receiverTracker = new ReceiverTracker(ssc)
receiverTracker.start()
jobGenerator.start()
logInfo("Started JobScheduler")
}

def submitJobSet(jobSet: JobSet) {
if (jobSet.jobs.isEmpty) {
logInfo("No jobs added for time " + jobSet.time)
} else {
jobSets.put(jobSet.time, jobSet)
jobSet.jobs.foreach(job => jobExecutor.execute(new JobHandler(job)))
logInfo("Added jobs for time " + jobSet.time)
}
}

private class JobHandler(job: Job) extends Runnable {
def run() {
eventActor ! JobStarted(job)
job.run()
eventActor ! JobCompleted(job)
}
}
job完成后处理
private def handleJobCompletion(job: Job) {
job.result match {
case Success(_) =>
val jobSet = jobSets.get(job.time)
jobSet.handleJobCompletion(job)
logInfo("Finished job " + job.id + " from job set of time " + jobSet.time)
if (jobSet.hasCompleted) {
jobSets.remove(jobSet.time)
jobGenerator.onBatchCompletion(jobSet.time)
logInfo("Total delay: %.3f s for time %s (execution: %.3f s)".format(
jobSet.totalDelay / 1000.0, jobSet.time.toString,
jobSet.processingDelay / 1000.0
))
listenerBus.post(StreamingListenerBatchCompleted(jobSet.toBatchInfo))
}
case Failure(e) =>
reportError("Error running job " + job, e)
}
}









spark streaming 4: DStreamGraph JobScheduler的更多相关文章

  1. Spark Streaming Backpressure分析

    1.为什么引入Backpressure 默认情况下,Spark Streaming通过Receiver以生产者生产数据的速率接收数据,计算过程中会出现batch processing time > ...

  2. Spark Streaming性能优化: 如何在生产环境下应对流数据峰值巨变

    1.为什么引入Backpressure 默认情况下,Spark Streaming通过Receiver以生产者生产数据的速率接收数据,计算过程中会出现batch processing time > ...

  3. 5. Spark Streaming高级解析

    5.1 DStreamGraph对象分析 在Spark Streaming中,DStreamGraph是一个非常重要的组件,主要用来: 1. 通过成员inputStreams持有Spark Strea ...

  4. 4. Spark Streaming解析

    4.1 初始化StreamingContext import org.apache.spark._ import org.apache.spark.streaming._ val conf = new ...

  5. Spark Streaming揭秘 Day25 StreamingContext和JobScheduler启动源码详解

    Spark Streaming揭秘 Day25 StreamingContext和JobScheduler启动源码详解 今天主要理一下StreamingContext的启动过程,其中最为重要的就是Jo ...

  6. Spark Streaming揭秘 Day3-运行基石(JobScheduler)大揭秘

    Spark Streaming揭秘 Day3 运行基石(JobScheduler)大揭秘 引子 作为一个非常强大框架,Spark Streaming兼具了流处理和批处理的特点.还记得第一天的谜团么,众 ...

  7. Spark Streaming源码分析 – JobScheduler

    先给出一个job从被generate到被执行的整个过程在JobGenerator中,需要定时的发起GenerateJobs事件,而每个job其实就是针对DStream中的一个RDD,发起一个Spark ...

  8. 贯通Spark Streaming JobScheduler内幕实现和深入思考

    本节主要内容: 一.SparkStreaming Job生成深度思考 二.SparkStreaming Job生成源码解析 JobScheduler的地位非常的重要,所有的关键都在JobSchedul ...

  9. Spark Streaming源码解读之JobScheduler内幕实现和深度思考

    本期内容 : JobScheduler内幕实现 JobScheduler深度思考 JobScheduler 是整个Spark Streaming调度的核心,需要设置多线程,一条用于接收数据不断的循环, ...

随机推荐

  1. 文档.Write()和文档.Writeln()石材

    文档.Write()和文档.Writeln()文档是Javascript对象,其中封装了许多有用的方法,其中Write()和Writeln()是直接从浏览器窗口输出文本信息的方法.文件.Write() ...

  2. clientHeight和offsetHeight

    clientHeight:包括padding但不包括border.水平滚动条.margin的元素的高度.对于inline的元素这个属性一直是0,单位px,只读元素. offsetHeight:包括pa ...

  3. Linux 链接脚本分析

    作者:答疑助手lizuobin 原文: https://blog.csdn.net/lizuobin2/article/details/51779064 在前面学习的过程中,看代码时遇到 arch_i ...

  4. 解决myeclipse没有代码提示的问题

    今天和室友安装了一样的myeclipse版本,结果室友的自动提示功能有,我的输入“.”后却不能提示,这对我们敲代码简直来说是一个折磨,不能自动提示,本来还以为是系统问题,一个是win7,一个是win1 ...

  5. windows消息的循环机制

    首先来了解几个基本概念: 消息:在了解什么是消息先来了解什么是事件.事件可分为几种,由输入设备触发的,比如鼠标键盘等等.由窗体控件触发的,比如button控件,file菜单等.还有就是来自Window ...

  6. 【audition CC】将3分钟的歌曲无缝延长到15分钟

  7. CF981F 二分+Hall定理

    对于一个二分的答案 假设存在一个点集使得不满足Hall定理 题中给定的信息说明 左边每个点对应的右边点是一个区间 如果当前点集对应的右边区间是若干个不相交的区间组成的话说明我们还可以找到一个更小的点集 ...

  8. Scrapy爬取小说简单逻辑

    Scrapy爬取小说简单逻辑 一 准备工作 1)安装Python 2)安装PIP 3)安装scrapy 4)安装pywin32 5)安装VCForPython27.exe ........... 具体 ...

  9. [易学易懂系列|rustlang语言|零基础|快速入门|(26)|实战3:Http服务器(多线程版本)]

    [易学易懂系列|rustlang语言|零基础|快速入门|(26)|实战3:Http服务器(多线程版本)] 项目实战 实战3:Http服务器 我们今天来进一步开发我们的Http服务器,用多线程实现. 我 ...

  10. h5 rem计算

    设置html默认font-size: 100px,此时默认的页面的width是750px,然后根据手机大小改变html节点的font-size,从而改变rem的大小,代码如下: <script& ...