关闭

Spark UI详解

标签: spark源码UI
881人阅读 评论(0) 收藏 举报
分类:

在大型分布式系统中,采用事件监听机制是最常见的。如果Spark UI采用Scala的函数调用方式,由于函数调用多数情况下是同步调用,导致线程被阻塞。将函数调用更换为发送事件,事件的处理时异步的,当前线程可以继续执行后续逻辑,线程池中的线程还可以被重用,这样整个系统的并发度会大大增加。发送的事件会存入缓存,由定时调度器取出后,分配给监听此事件的监听器对监控数据进行更新。


Spark <wbr>UI详解

DAGScheduler是主要的产生各类SparkListenerEvent的源头,它将各种SparkListenerEvent发送到ListenerBus的事件队列中,ListenerBus通过定时器将SparkListenerEvent事件匹配到具体的SparkListener,改变SparkListener中的统计监控数据,最终由SparkUI的界面展示。


listenerBus详解

listenerBus的类型是LiveListenerBusLiveListenerBus实现了监听器模型,通过监听事件触发对各种监听器监听状态信息的修改,达到UI界面的数据刷新效果。LiveListenerBus继承自AsynchronousListenerBusAsynchronousListenerBus由如下部分组成:

·事件阻塞队列:LinkedBlockingQueue[SparkListenerEvent],固定大小是10000

·监听器数组:类型为ArrayBuffer[SparkListener],存放各类监听器SparkListener

·事件匹配监听器的线程:此Thread不断拉取LinkedBlockingQueue中的事件,遍历监听器,调用监听器的方法。任何事件都会在LinkedBlockingQueue中存在一段时间,然后Thread处理了此事件后,会将其清除。


构造JobProgressListener

JobProgressListener为例讲解SparkListener。通过监听ListenerBus中的事件更新任务进度。SparkStatusTrackerSparkUI实际上也是通过JobProgressListener来实现任务状态跟踪的。

JobProgressListener实现了onJobStartonJobEndonStageCompletedonStageSubmittedonTaskStartonTaskEnd等方法,这些方法是在listenerBus的驱动下,改变JobProgressListener中的各种JobStage相关的数据。


SparkUI的创建与初始化

private def create(
    sc: Option[SparkContext],
    conf: SparkConf,
    listenerBus: SparkListenerBus,
    securityManager: SecurityManager,
    appName: String,
    basePath: String = "",
    jobProgressListener: Option[JobProgressListener] = None,
    startTime: Long): SparkUI = {

  val _jobProgressListener: JobProgressListener = jobProgressListener.getOrElse {
    val listener = new JobProgressListener(conf)
    listenerBus.addListener(listener)
    listener
  }

  val environmentListener = new EnvironmentListener
  val storageStatusListener = new StorageStatusListener
  val executorsListener = new ExecutorsListener(storageStatusListener)
  val storageListener = new StorageListener(storageStatusListener)
  val operationGraphListener = new RDDOperationGraphListener(conf)

  listenerBus.addListener(environmentListener)
  listenerBus.addListener(storageStatusListener)
  listenerBus.addListener(executorsListener)
  listenerBus.addListener(storageListener)
  listenerBus.addListener(operationGraphListener)

  new SparkUI(sc, conf, securityManager, environmentListener, storageStatusListener,
    executorsListener, _jobProgressListener, storageListener, operationGraphListener,
    appName, basePath, startTime)
}

create方法里除了JobprogressListener是外部传入的之外,又增加了一些SparkListener。例如用于对JVM参数、Spark属性、Java系统属性、classpath等进行监控的EnvironmentListener;用于维护Executor的存储状态的StorageStatusListener;用于准备将Executor的信息展示在ExecutorTabExecutorListener;用于准备将Executor相关存储信息展示在BlockManagerUIstorageListener等。最后,创建SparkUISparkUI服务默认是可以杀掉 的,设置spark.ui.killEnabledfalse可以保证不被杀死。

Initialize方法会组织前端页面各个TabPage的展示及布局。


SparkUI的页面布局与展示

JobsTab展示所有Job的进度,状态信息,以它为例说明。JobsTab会复用SparkUIkillEnabledSparkContextjobProgressListener,包括AllJobsPageJobPage两个页面。

private[ui] class JobsTab(parent: SparkUI) extends SparkUITab(parent, "jobs") {
  val sc = parent.sc
  val killEnabled = parent.killEnabled
  val jobProgresslistener = parent.jobProgressListener
  val executorListener = parent.executorsListener
  val operationGraphListener = parent.operationGraphListener

  def isFairScheduler: Boolean =
    jobProgresslistener.schedulingMode.exists(_ == SchedulingMode.FAIR)

  attachPage(new AllJobsPage(this))
  attachPage(new JobPage(this))
}

AllJobsPagerender方法渲染,利用JobProgressListener中的统计监控数据生成激活、完成、失败等状态的Job摘要信息,并调用jobsTable方法生成表格等html元素,最终使用UIUtilsheaderSparkPage封装好cssjsheader及页面布局等。

上面的attachPage方法存在于JobsTab的父类WebUITab中,WebUITab维护有ArrayBuffer[WebUIPage]的数据结构,AllJobsPageJobPage将被放入此ArrayBuffer中。

private[spark] abstract class WebUITab(parent: WebUI, val prefix: String) {
  val pages = ArrayBuffer[WebUIPage]()
  val name = prefix.capitalize

  
  def attachPage(page: WebUIPage) {
    page.prefix = (prefix + "/" + page.prefix).stripSuffix("/")
    pages += page
  }

  
  def headerTabs: Seq[WebUITab] = parent.getTabs

  def basePath: String = parent.getBasePath
}
JobsTab创建之后,被attachTab方法加入SparkUIArrayBuffer[WebUITab]中,并且通过attachPage方法,将每个page生成org.apache.jetty.servlet.ServletContextHandler,最后调用attachHandler方法将ServletContextHandler绑定到SparkUI
def attachTab(tab: WebUITab) {
  tab.pages.foreach(attachPage)
  tabs += tab
}
def attachPage(page: WebUIPage) {
  val pagePath = "/" + page.prefix
  val renderHandler = createServletHandler(pagePath,
    (request: HttpServletRequest) => page.render(request), securityManager, conf, basePath)
  val renderJsonHandler = createServletHandler(pagePath.stripSuffix("/") + "/json",
    (request: HttpServletRequest) => page.renderJson(request), securityManager, conf, basePath)
  attachHandler(renderHandler)
  attachHandler(renderJsonHandler)
  pageToHandlers.getOrElseUpdate(page, ArrayBuffer[ServletContextHandler]())
    .append(renderHandler)
}
def attachHandler(handler: ServletContextHandler) {
  handlers += handler
  serverInfo.foreach { info =>
    info.rootHandler.addHandler(handler)
    if (!handler.isStarted) {
      handler.start()
    }
  }
}


SparkUI的启动

SparkUI创建好后,需要调用父类WebUIbind方法,绑定服务和端口。

def bind() {
  assert(!serverInfo.isDefined, "Attempted to bind %s more than once!".format(className))
  try {
    serverInfo = Some(startJettyServer("0.0.0.0", port, handlers, conf, name))
    logInfo("Started %s at http://%s:%d".format(className, publicHostName, boundPort))
  } catch {
    case e: Exception =>
      logError("Failed to bind %s".format(className), e)
      System.exit(1)
  }
}
startJettyServerJettyUtils的静态方法,最终启动Jetty提供的服务。






0
1
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

spark webui的展示

在standalone模式下,运行一个应用,我们来操作webui查看一些信息 主页主页展示了如下信息 概览 工作中的slave 运行中的应用 已经完成的应用 slave信息点击Workers列表中Wo...
  • qhshiniba
  • qhshiniba
  • 2016-09-02 23:44
  • 1670

Spark配置参数详解

以下是整理的Spark中的一些配置参数,官方文档请参考Spark Configuration。 Spark提供三个位置用来配置系统: Spark属性:控制大部分的应用程序参数,可以用SparkCon...
  • guohecang
  • guohecang
  • 2016-08-01 20:26
  • 31525

Spark UI界面原理

本文以Spark-1.6.0源码为基础,分析了Spark UI界面的框架构成,及页面数据展示方法。
  • dabokele
  • dabokele
  • 2016-07-06 23:21
  • 12350

spark内核揭秘-08-spark的Web监控页面

spark内核揭秘-08-spark的Web监控页面 spark内核揭秘-08-spark的Web监控页面 spark内核揭秘-08-spark的Web监控页面 spark内核揭秘-08-spark的...
  • stark_summer
  • stark_summer
  • 2015-01-20 12:42
  • 20954

spark的UI界面

[看图说话] 基于Spark UI性能优化与调试——初级篇 Spark有几种部署的模式,单机版、集群版等等,平时单机版在数据量不大的时候可以跟传统的java程序一样进行断电调...
  • u013013024
  • u013013024
  • 2017-06-20 15:16
  • 1386

第43课:Spark Streaming中UI内幕实现彻底解密

第43课:Spark Streaming中UI内幕实现彻底解密 1 spark streaming中UI的监听器模式 2 spark streaming中UI具体源码解析
  • duan_zhihua
  • duan_zhihua
  • 2016-07-12 06:42
  • 470

spark on yarn图形化任务监控利器:History-server帮你理解spark的任务执行过程

在spark on yarn任务进行时,大家都指导用4040端口监控(默认是,设置其他或者多个任务同时会递增等例外); 辣么,任务结束了,还要看图形化界面,那就要开history-server了。C...
  • oufuji
  • oufuji
  • 2015-12-21 10:45
  • 4679

Spark知识体系完整解读

来源 http://mt.sohu.com/20160522/n450849016.shtml 作者:杨思义,2014年6月至今工作于北京亚信智慧数据科技有限公司 BDX大数据事业部,从2014...
  • zy_zhengyang
  • zy_zhengyang
  • 2016-06-03 19:30
  • 3309

spark入门详解

1. Spark中的基本概念 在Spark中,有下面的基本概念。 Application:基于Spark的用户程序,包含了一个driver program和集群中多个executor Dri...
  • anningzhu
  • anningzhu
  • 2017-03-07 20:24
  • 2220

Spark 提交任务详解

Running Spark on YARNcluster mode :$ ./bin/spark-submit --class org.apache.spark.examples.SparkPi \ ...
  • OiteBody
  • OiteBody
  • 2016-12-09 17:18
  • 1155
    个人资料
    • 访问:12682次
    • 积分:232
    • 等级:
    • 排名:千里之外
    • 原创:9篇
    • 转载:13篇
    • 译文:0篇
    • 评论:3条
    文章分类
    最新评论