3.9 启动测量系统MetricsSystem

MetricsSystem使用codahale提供的第三方测量仓库Metrics,有关Metrics的具体信息可以参考附录D。MetricsSystem中有三个概念:

Instance:指定了谁在使用测量系统;

Source:指定了从哪里收集测量数据;

Sink:指定了往哪里输出测量数据。

Spark按照Instance的不同,区分为Master、Worker、Application、Driver和Executor。

Spark目前提供的Sink有ConsoleSink、CsvSink、JmxSink、MetricsServlet、GraphiteSink等。

Spark中使用MetricsServlet作为默认的Sink。

MetricsSystem的启动代码如下。

val metricsSystem = env.metricsSystem

metricsSystem.start()

MetricsSystem的启动过程包括以下步骤:

1)注册Sources;

2)注册Sinks;

3)给Sinks增加Jetty的ServletContextHandler。

MetricsSystem启动完毕后,会遍历与Sinks有关的ServletContextHandler,并调用attach-Handler将它们绑定到Spark UI上。

metricsSystem.getServletHandlers.foreach(handler => ui.foreach(_.attachHandler (handler)))

3.9.1 注册Sources

registerSources方法用于注册Sources,告诉测量系统从哪里收集测量数据,它的实现见代码清单3-45。注册Sources的过程分为以下步骤:

1)从metricsConfig获取Driver的Properties,默认为创建MetricsSystem的过程中解析的{sink.servlet.class=org.apache.spark.metrics.sink.MetricsServlet, sink.servlet.path=/metrics/json}。

2)用正则匹配Driver的Properties中以source.开头的属性。然后将属性中的Source反射得到的实例加入ArrayBuffer[Source]。

3)将每个source的metricRegistry(也是MetricSet的子类型)注册到Concurrent-Map<String, Metric> metrics。这里的registerSource方法已在3.8.2节讲解过。

代码清单3-45 MetricsSystem注册Sources的实现

private def registerSources() {

val instConfig = metricsConfig.getInstance(instance)

val sourceConfigs = metricsConfig.subProperties(instConfig, MetricsSystem.SOURCE_REGEX)

// Register all the sources related to instance

sourceConfigs.foreach { kv =>

val classPath = kv._2.getProperty("class")

try {

val source = Class.forName(classPath).newInstance()

registerSource(source.asInstanceOf[Source])

} catch {

case e: Exception => logError("Source class " + classPath + " cannot be instantiated", e)

}

}

}

3.9.2 注册Sinks

registerSinks方法用于注册Sinks,即告诉测量系统MetricsSystem往哪里输出测量数据,它的实现见代码清单3-46。注册Sinks的步骤如下:

1)从Driver的Properties中用正则匹配以sink.开头的属性,如{sink.servlet.class=org.apache.spark.metrics.sink.MetricsServlet, sink.servlet.path=/metrics/json},将其转换为Map(servlet -> {class=org.apache.spark.metrics.sink.MetricsServlet, path=/metrics/json})。

2)将子属性class对应的类metricsServlet反射得到MetricsServlet实例。如果属性的key是servlet,将其设置为metricsServlet;如果是Sink,则加入到ArrayBuffer[Sink]中。

代码清单3-46 MetricsSystem注册Sinks的实现

private def registerSinks() {

val instConfig = metricsConfig.getInstance(instance)

val sinkConfigs = metricsConfig.subProperties(instConfig, MetricsSystem.SINK_REGEX)

sinkConfigs.foreach { kv =>

val classPath = kv._2.getProperty("class")

if (null != classPath) {

try {

val sink = Class.forName(classPath)

.getConstructor(classOf[Properties], classOf[MetricRegistry], classOf[SecurityManager])

.newInstance(kv._2, registry, securityMgr)

if (kv._1 == "servlet") {

metricsServlet = Some(sink.asInstanceOf[MetricsServlet])

} else {

sinks += sink.asInstanceOf[Sink]

}

} catch {

case e: Exception => logError("Sink class "+ classPath + " cannot be instantialized",e)

}

}

}

}

3.9.3 给Sinks增加Jetty的ServletContextHandler

为了能够在SparkUI(网页)访问到测量数据,所以需要给Sinks增加Jetty的Servlet-ContextHandler,这里主要用到MetricsSystem的getServletHandlers方法实现如下。

def getServletHandlers = {

require(running, "Can only call getServletHandlers on a running MetricsSystem")

metricsServlet.map(_.getHandlers).getOrElse(Array())

}

可以看到调用了metricsServlet的getHandlers,其实现如下。

def getHandlers = Array[ServletContextHandler](

createServletHandler(servletPath,

new ServletParams(request => getMetricsSnapshot(request), "text/json"), securityMgr)

)

最终生成处理/metrics/json请求的ServletContextHandler,而请求的真正处理由get-MetricsSnapshot方法,利用fastjson解析。生成的ServletContextHandler通过SparkUI的attachHandler方法,也被绑定到SparkUI(creatServlethandler与attachHandler方法在3.4.4节详细讲述过)。最终我们可以使用以下这些地址来访问测量数据。

http://localhost:4040/metrics/applications/json。

http://localhost:4040/metrics/json。

http://localhost:4040/metrics/master/json。

深入理解Spark:核心思想与源码分析. 3.9 启动测量系统MetricsSystem相关推荐

  1. 《深入理解Spark:核心思想与源码分析》——1.2节Spark初体验

    本节书摘来自华章社区<深入理解Spark:核心思想与源码分析>一书中的第1章,第1.2节Spark初体验,作者耿嘉安,更多章节内容可以访问云栖社区"华章社区"公众号查看 ...

  2. 《深入理解Spark:核心思想与源码分析》——第1章环境准备

    本节书摘来自华章社区<深入理解Spark:核心思想与源码分析>一书中的第1章环境准备,作者耿嘉安,更多章节内容可以访问云栖社区"华章社区"公众号查看 第1章 环 境 准 ...

  3. 《深入理解Spark:核心思想与源码分析》——3.10节创建和启动ExecutorAllocationManager...

    本节书摘来自华章社区<深入理解Spark:核心思想与源码分析>一书中的第3章,第3.10节创建和启动ExecutorAllocationManager,作者耿嘉安,更多章节内容可以访问云栖 ...

  4. 《深入理解Spark:核心思想与源码分析》——1.3节阅读环境准备

    本节书摘来自华章社区<深入理解Spark:核心思想与源码分析>一书中的第1章,第1.3节阅读环境准备,作者耿嘉安,更多章节内容可以访问云栖社区"华章社区"公众号查看 1 ...

  5. 深入理解Spark:核心思想与源码分析

    大数据技术丛书 深入理解Spark:核心思想与源码分析 耿嘉安 著 图书在版编目(CIP)数据 深入理解Spark:核心思想与源码分析/耿嘉安著. -北京:机械工业出版社,2015.12 (大数据技术 ...

  6. 《深入理解Spark:核心思想与源码分析》——SparkContext的初始化(叔篇)——TaskScheduler的启动...

    <深入理解Spark:核心思想与源码分析>一书前言的内容请看链接<深入理解SPARK:核心思想与源码分析>一书正式出版上市 <深入理解Spark:核心思想与源码分析> ...

  7. 《深入理解SPARK:核心思想与源码分析》(第1章)

    自己牺牲了7个月的周末和下班空闲时间,通过研究Spark源码和原理,总结整理的<深入理解Spark:核心思想与源码分析>一书现在已经正式出版上市,目前亚马逊.京东.当当.天猫等网站均有销售 ...

  8. spring源码分析第五天------springAOP核心原理及源码分析

    spring源码分析第五天------springAOP核心原理及源码分析 1. 面向切面编程.可以通过预 编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术 切面(A ...

  9. spring源码分析第四天------springmvc核心原理及源码分析

    spring源码分析第四天------springmvc核心原理及源码分析 1.基础知识普及 2. SpringMVC请求流程 3.SpringMVC代码流程 4.springMVC源码分析 4.1 ...

最新文章

  1. java8新特性(四)_Stream详解
  2. lodop打印不显示页码_Lodop插件实现打印功能
  3. Java黑皮书课后题第4章:*4.2(几何:最大圆距离)最大圆面积是指球面上两个点间的距离。编写一个程序,提示用户以度为单位输入地球上两个点的经纬度,显示其最大圆距离值
  4. Jsoup遍历ul li下的链接信息实例
  5. 手把手带你入门Python爬虫(二、爬虫预备知识)
  6. JavaWeb学习笔记-kuangshen
  7. 用 Mac 制作手写签名,没打印机也能搞事
  8. linux下redis安装教程
  9. svn 客户端下载地址
  10. 方正字库的手写字体开始出真GBK了
  11. windows server 2012 AD 活动目录部署系列(二)创建域控制器
  12. 机器学习(Machine Learning and Data Mining)CS 5751——final复习记录(3)
  13. 倒计时1天,六位专家周末带你解锁前端研发新姿势
  14. Linux java进程CPU占用过高解决方案
  15. 程序员为什么害怕低代码?
  16. 坤音键盘(ikun专用)
  17. 多媒体融合通信系统在铁路系统编组站的应用
  18. Composer安装Laravel最简单、详细图解
  19. day 09--函数和模块
  20. 杰里之 定时器捕获(timer_cap.c) 使用注意事项【篇】

热门文章

  1. 3.1线性判别函数【模式识别】
  2. 可以接受失败,但不选择放弃
  3. 方法apply作用于对象sort时失败_浅析call、apply 与 bind
  4. 命令注入工具Commix
  5. Swift2.0语言教程之下标脚本
  6. ArduinoYun快速入门教程第1章ArduinoYun概览
  7. centos mysql压缩文件直接恢复_Centos下mysql数据库备份与恢复的方法
  8. UITextFiled使用 + 不常见的需求
  9. python的x 2是什么意思_python中startx是什么意思
  10. 线程安全机制 python