spark 2.4.0源码分析--(一)事件总线LiveListenerBus

spark事件总线的核心是LiveListenerBus,其内部维护了多个AsyncEventQueue队列用于存储和分发和响应SparkListenerEvent事件。
spark事件总线整体思想是生产消费者模式,消息事件实现了先进先出和异步投递,同时将事件的产生(例如DAGScheduler创建stage、提交job)和事件的处理(例如在Spark UI显示任务信息)分离,在一定程度上提升了系统的异步处理性能,是一个经典的事件处理模式。

一、LiveListenerBus 总体结构及监听器介绍

在这里插入图片描述

  1. 在queues:CopyOnWriteArrayList[AsyncEventQueue]中,目前主要有4种命名队列(AsyncEventQueue),对应了4个addToXXXXQueue()方法。由图中左侧可知,每种命名队列有1~2个不同SparkListenerInterface实现,总共有大约10种不同功能listener添加到总线中。
  2. addToSharedQueue(),主要由SparkContext调用,即用户可以在代码中增加Listener,或从配单中增加Listener并反射调用[实现在setupAndStartListenerBus()]
  3. addToManagementQueue(),分别可增加HeartbeatReceiver(用于监听Executor的Add和Remove,并使用线程定期判断各Executor的心跳时间,超时则Kill
    Executor),另外可通过ExecutorAllocationManager增加ExecutorAllocationListener(通过计算总task数和Excutor并行度进行匹配,动态增加、减少Executor,需要配置,默认关闭)
  4. addToStatusQueue(),主要增加了AppStatusListener,为AppStatusStore提供Job、Stage、Task的UI展示数据,以及增加了SQLAppStatusListener,为SQLAppStatesStore提供SQL
    UI展示数据,在本文后续章节KVStore中介绍
  5. addToEventLogQueue(),将监听到的事件以Json方式写出到日志存储,需要配置,默认为关闭
  6. 前面几个方法内部均调用addToQueue()方法,还有一种情况,spark structured streaming流式计算对应的StreamingQueryListenerBus通过addToQueue()方法加入"streams"队列(用于监听流的start、process、terminate时间,其中process事件能获取到流处理的详细进度,包括流名称、id、水印时间、source offsets、sink offsets等)。
private[spark] class LiveListenerBus(conf: SparkConf) {

  ...

  private val queues = new CopyOnWriteArrayList[AsyncEventQueue]()

  @volatile private[scheduler] var queuedEvents = new mutable.ListBuffer[SparkListenerEvent]()

  def addToSharedQueue(listener: SparkListenerInterface): Unit = {
    addToQueue(listener, SHARED_QUEUE)
  }

  def addToManagementQueue(listener: SparkListenerInterface): Unit = {
    addToQueue(listener, EXECUTOR_MANAGEMENT_QUEUE)
  }

  def addToStatusQueue(listener: SparkListenerInterface): Unit = {
    addToQueue(listener, APP_STATUS_QUEUE)
  }

  def addToEventLogQueue(listener: SparkListenerInterface): Unit = {
    addToQueue(listener, EVENT_LOG_QUEUE)
  }

  // addToQueue实际上是调用了具体某个命名Queue的addListener()
  private[spark] def addToQueue(
      listener: SparkListenerInterface,
      queue: String): Unit = synchronized {
    ...

    queues.asScala.find(_.name == queue) match {
      case Some(queue) =>
        queue.addListener(listener)

      case None =>
        val newQueue = new AsyncEventQueue(queue, conf, metrics, this)
        newQueue.addListener(listener)
        if (started.get()) {
          newQueue.start(sparkContext)
        }
        queues.add(newQueue)
    }
  }

  ...
}

二、向LiveListenerBus投递事件

1、事件类型SparkListenerEvent

事件类型SparkListenerEvent一个trait特质,其实现的子类较多,一般为当前事件的详细信息,可用于展示或记录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值