spark2.2.0源码分析

程序入口,前面参数初始化略过 。。。。
首先调用createSparkEnv 创建env
// Create the Spark execution environment (cache, map output tracker, etc)
_env = createSparkEnv(_conf, isLocal, listenerBus)
SparkEnv.set(_env)

1.首先来看listenerBus
事件对象
事件监听模式 事件源
时间监听器
sparkContext中初始化该LiveListenerBus
// An asynchronous listener bus for Spark events
private[spark] val listenerBus = new LiveListenerBus(this)

//Asynchronously passes SparkListenerEvents to registered SparkListeners.
//异步地将SparkListenerEvents传递给已经注册过的SparkListeners
LiveListenerBus :
//用于放置 SparkListenerEvent 事件的阻塞队列 容量可通过参数设置
private lazy val eventQueue = new LinkedBlockingQueue[SparkListenerEvent]

//用于标明LiveListenerBus是否启动
private val started = new AtomicBoolean(false)

//用于标明LiveListenerBus是否停止
private val stopped = new AtomicBoolean(false)

//用于统计删除event的数据,每当日志打印了该值,则重置为0
private val droppedEventsCounter = new AtomicLong(0L)

//用于记录打印droppedEventsCounter 的时间戳
@volatile private var lastReportTimestamp = 0L

//用于标明当前listenerThread正在处理event
private var processingEvent = false

//用于标明队列是否已满,导致新的事件不能进入队列从而被删除
private val logDroppedEvent = new AtomicBoolean(false)

//用于当有新的事件到来时释放信号量,当对事件进行处理时获取信号量
private val eventLock = new Semaphore(0)

//处理事件的线程
private val listenerThread = new Thread(name) {
setDaemon(true)
override def run(): Unit = Utils.tryOrStopSparkContext(sparkContext) {
LiveListenerBus.withinListenerThread.withValue(true) {
while (true) {
//获取信号量,当有信号量存在时说明还有未处理的event
eventLock.acquire()
self.synchronized {
//设置当前正在处理event
processingEvent = true
}
try {
//从eventQueue中获取event
val event = eventQueue.poll
if (event == null) {
// Get out of the while loop and shutdown the daemon thread
if (!stopped.get) {
throw new IllegalStateException(“Polling null from eventQueue means” +
" the listener bus has been stopped. So stopped must be true")
}
return
}
//使用父类ListenerBus的postToAll将event发送到注册过的所有listener上
postToAll(event)
} finally {
self.synchronized {
//将当前正在处理event状态标记为false
processingEvent = false
}
}
}
}
}
}

listener 相关博客 https://www.pianshen.com/article/32472081/

2.接着来看createSparkEnv方法
该方法最终调用SparkEnv的create方法,进入方法内部,最终 new SparkEnv(…)来创建了SparkEnv
val envInstance = new SparkEnv(
executorId,
rpcEnv,
serializer,
closureSerializer,
serializerManager,
mapOutputTracker,
shuffleManager,
broadcastManager,
blockManager,
securityManager,
metricsSystem,
memoryManager,
outputCommitCoordinator,
conf)
到此,SparkEnv对象初始化完成

3.开始创建TaskScheduler
// Create and start the scheduler
val (sched, ts) = SparkContext.createTaskScheduler(this, master, deployMode)
根据不同模式创建不同的TaskScheduler 和 SchedulerBackend

4.创建DAGScheduler,最终使用 SparkContext对象创建DAGScheduler
_dagScheduler = new DAGScheduler(this) ====>>>> def this(sc: SparkContext) = this(sc, sc.taskScheduler)

5.将DAGScheduler对象注入到taskScheduler中
taskScheduler.setDAGScheduler(this)
6.启动TaskScheduler
_taskScheduler.start()

RpcEndPoint 表示需要通信的对象
RpcEndpointRef 对远程RpcEndpoint的一个引用,需要获取引用之后,通过该引用发送消息
RpcEnv 为RpcEndPoint提供处理消息的环境,负责RpcEndPoint整个生命周期的管理
相关博客 https://blog.csdn.net/qq_35078688/article/details/88342371

createSparkEnv(_conf, isLocal, listenerBus) 中通过 SparkEnv 创建Driver端的运行环境SparkEnv.createDriverEnv(conf, isLocal, listenerBus, SparkContext.numDriverCores(master))

通过set方法将创建好的DriverEnv拿过来
def set(e: SparkEnv) {
env = e
}
object SparkEnv extends Logging {
@volatile private var env: SparkEnv = _

}

接着来看 createSparkEnv 方法
private[spark] def createSparkEnv(
conf: SparkConf,
isLocal: Boolean,
listenerBus: LiveListenerBus): SparkEnv = {
SparkEnv.createDriverEnv(conf, isLocal, listenerBus, SparkContext.numDriverCores(master))
}
第一步:创建了Driver端的运行环境 _env :
SparkEnv.createDriverEnv(conf, isLocal, listenerBus, SparkContext.numDriverCores(master)

第二步:创建taskScheduler
val (sched, ts) = SparkContext.createTaskScheduler(this, master, deployMode)
_schedulerBackend = sched
_taskScheduler = ts

第三步:创建DagScheduler
_dagScheduler = new DAGScheduler(this)
创建时需要taskScheduler
def this(sc: SparkContext) = this(sc, sc.taskScheduler)

第四步:启动taskScheduler _taskScheduler.start()

未完

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值