Spark WebUI是Spark HistoryServer提供的网页服务,可以展示Spark任务相关的历史记录信息,方便用户对任务进行分析和问题的排查。
1.Spark WebUI后端请求服务器初始化过程
Spark HistoryServer在启动过程中,会启动一个Jetty容器,容器中运行的servlet服务可以接收Web端的请求,并返回网页内容用于浏览器渲染页面。
Jetty容器的启动过程如下所示:
HistoryServer#main
historyServer = new HistoryServer() extends WebUI(name = "HistoryServerUI", poolSize = 1000) // 定义了线程名称
historyServer.bind()
WebUI.bind()
WebUI.initServer()
WebUI.startJettyServer(name, poolSize)
pool = new org.eclipse.jetty.util.thread.QueuedThreadPool(poolSize) // 设置线程池最多线程大小,最小线程数为Math.min(8, poolSize)
pool.setName(name) // 设置线程名称
pool.setDaemon(true) // 设置为守护线程
server = new org.eclipse.jetty.server.Server(pool)
server.start()
这里可以看到,接收请求的线程名称前缀为HistoryServerUI,而且对于最大和最小线程数有一个明确的设置。
2.Spark WebUI页面定义
每个Spark WebUI页面都对应一个Scala类,共有21种页面,如下所示:
WebUIPage
AllExecutionsPage
AllJobsPage
AllStagesPage
ApplicationPage
BatchPage
EnvironmentPage
ExecutionPage
ExecutorThreadDumpPage
ExecutorsPage
HistoryPage
JobPage
LogPage
MasterPage
PoolPage
RDDPage
StagePage
StoragePage
StreamingPage
StreamingQueryPage
StreamingQueryStatisticsPage
WorkerPage
这些Page类需继承org.apache.spark.ui.WebUIPage这个抽象类,WebUIPage中定义了需要实现的方法:
// prefix表示页面的path
private[spark] abstract class WebUIPage(var prefix: String) {
// 用于返回渲染页面的html内容
def render(request: HttpServletRequest): Seq[Node]
// 用于获取页面的数据信息
def renderJson(request: HttpServletRequest): JValue = JNothing
}
页面定义有了后,至于页面与url的映射关系是怎么样的呢?要回答这个问题,需要进入到WebUITab的设计中。
3.WebUITab页面管理
WebUITab就是一些WebUIPage的集合,可以更好地管理这些WebUIPage。WebUITab中定义了prefix,与WebUIPage中的prefix一起决定了这个页面的url path。下面是当前WebUITab与WebUIPage的映射关系。
WebUITab
SparkUITab
EnvironmentTab(prefix = "environment")
EnvironmentPage(prefix = "") // page path /environment
ExecutorsTab(prefix = "executors")
ExecutorsPage(prefix = "") // page path /executors
ExecutorThreadDumpPage(prefix = "threadDump") // page path /executors/threadDump
ExecutorHeapHistogramPage(prefix = "heapHistogram") // page path /executors/heapHistogram
JobsTab(prefix = "jobs")
AllJobsPage(prefix = "") // page path /jobs
JobPage(prefix = "job") // page path /jobs/job
SQLTab(prefix = "SQL")
AllExecutionsPage(prefix = "") // page path /SQL
ExecutionPage(prefix = "execution") // page path /SQL/execution
SparkConnectServerTab(prefix = "connect")
SparkConnectServerPage(prefix = "") // page path /connect
SparkConnectServerSessionPage(prefix = "session") // page path /connect/session
StagesTab(prefix = "stages")
AllStagesPage(prefix = "") // page path /stages
StagePage(prefix = "stage") // page path /stages/stage
PoolPage(prefix = "pool") // page path /stages/pool
StorageTab(prefix = "storage")
StoragePage(prefix = "") // page path /storage
RDDPage(prefix = "rdd") // page path /storage/rdd
StreamingQueryTab(prefix = "StreamingQuery")
StreamingQueryPage(prefix = "") // page path /StreamingQuery
StreamingQueryStatisticsPage(prefix = "statistics") // page path /StreamingQuery/statistics
StreamingTab(prefix = "streaming")
StreamingPage(prefix = "") // page path /streaming
BatchPage(prefix = "batch") // page path /streaming/batch