【Spark ML系列】Spark Instrumentation OptionalInstrumentation 功能用法示例源码详解点击这里看全文
原理
Spark Instrumentation 的原理是通过在关键代码路径中插入记录和度量的逻辑来实现。它使用了 Spark 内置的监控指标和事件机制,以及自定义的 Instrumentation 类和相关工具。
具体来说,Spark Instrumentation 的原理包括以下几个关键步骤:
-
Spark 内置监控指标:Spark 提供了一组内置的监控指标,用于度量应用程序的性能。这些指标包括任务执行时间、内存使用情况、数据读写速度等。Instrumentation 利用这些指标来收集有关应用程序运行时性能的信息。
-
Instrumentation 类:Instrumentation 是一个自定义的类,用于封装记录和度量逻辑。它提供了一系列方法,如记录流水线阶段、数据集信息、参数值、特定值等。Instrumentation 类还可以记录不同级别的日志,并使用唯一标识训练会话的前缀。
-
记录关键代码路径:在关键代码路径中,例如训练会话的开始、结束以及重要操作的执行过程中,插入对 Instrumentation 方法的调用。这样就能够捕获和记录与性能相关的信息,如流水线阶段、数据集、参数值等。
-
事件机制:Spark 提供了事件机制,允许应用程序在关键事件发生时触发自定义逻辑。Instrumentation 可以利用这个事件机制,在关键事件发生时发送自定义的 MLEvent。通过自定义的 MLEvent,可以记录特定值、状态转换等与性能相关的信息。
通过结合 Spark 内置的监控指标、自定义的 Instrumentation 类和事件机制,Spark Instrumentation 实现了对应用程序性能的监控和度量。开发人员可以通过仪表化代码路径和发送自定义事件,收集有关应用程序运行时性能的信息,并进行优化和调整。这样可以帮助开发人员更好地理解应用程序的行为、识别潜在的性能问题,并采取相应的措施来提高应用程序的性能和可伸缩性。
功能和使用
功能
Spark 中用于仪表化的 Instrumentation 类和 OptionalInstrumentation 类的实现。
- Instrumentation 类是一个小的包装器,用于定义训练会话、记录有用信息并发送 MLEvents。它提供了一系列方法来记录流水线阶段、数据集、参数值等相关信息,并具有记录不同级别日志的能力。
- OptionalInstrumentation 类是 Instrumentation 的可选包装器,它包含一个可选的 Instrumentation 对象。它提供了一系列方法来记录日志,并根据 Instrumentation 对象的定义情况,选择将日志记录到指定的对象或使用通用日志记录器。
如何使用
这些类可以通过以下方式使用:
- 创建 Instrumentation 对象,使用其提供的方法记录训练会话中的信息,如流水线阶段、数据集、参数值等。
- 使用 Instrumentation.instrumented 方法对代码块进行仪表化,在其中记录训练会话的信息。该方法会自动记录成功或失败的日志。
- 使用 OptionalInstrumentation 对象记录日志,可以选择将日志记录到指定的 Instrumentation 对象,或者使用通用日志记录器。
通过使用这些类,可以方便地在 Spark 应用程序中仪表化和记录有关训练会话的信息,以便分析和优化应用程序的性能。
方法
Instrumentation 类的方法:
logPipelineStage(stage: PipelineStage)
:记录流水线阶段的信息。logDataset(dataset: Dataset[_])
和logDataset(dataset: RDD[_])
:记录数据集的信息。logDebug(msg: => String)
、logWarning(msg: => String)
、logError(msg: => String)
和logInfo(msg: => String)
:记录不同级别的日志,并使用唯一标识训练会话的前缀。logParams(hasParams: Params, params: Param[_]*)
:记录估算器的参数值。logNumFeatures(num: Long)
、logNumClasses(num: Long)
、logNumExamples(num: Long)
和logSumOfWeights(num: Double)
:记录特定值,并使用自定义名称字段。logNamedValue(name: String, value: String)
、logNamedValue(name: String, value: Long)
、logNamedValue(name: String, value: Double)
、logNamedValue(name: String, value: Array[String])
、logNamedValue(name: String, value: Array[Long])
和logNamedValue(name: String, value: Array[Double])
:记录具有自定义名称字段的值。logSuccess()
和logFailure(e: Throwable)
:记录成功或失败的训练会话。
OptionalInstrumentation 类的方法:
logInfo(msg: => String)
、logWarning(msg: => String)
和logError(msg: => String)
:记录日志,根据是否存在 Instrumentation 对象来选择记录方式。
Instrumentation 伴生对象的方法:
instrumented[T](body: (Instrumentation => T)): T
:对代码块进行仪表化,自动记录成功或失败的日志。
OptionalInstrumentation 伴生对象的方法:
create(instr: Instrumentation): OptionalInstrumentation
和create(clazz: Class[_]): OptionalInstrumentation
:创建 OptionalInstrumentation 对象,用于根据是否存在 Instrumentation 对象选择记录日志的方式。
这些方法提供了方便的接口来记录有关训练会话的信息,包括流水线阶段、数据集、参数值等。
同时,它们还具备了自动记录成功或失败的日志功能,使得应用程序的仪表化和日志记录更加简单和高效。
示例
可以按照以下步骤使用这些类:
1. 导入必要的依赖:
import org.apache.spark.ml.param.Param
import org.apache.spark.ml.util.{
MLEvents, Params}
import org.apache.spark.ml.PipelineStage
import org.apache.spark.internal.Logging
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{
Dataset, SparkSession}
import org.json4s.JsonAST.{
JValue, compact, parse, render}
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods.{
map2jvalue, pretty, render}
import scala.util.{
Failure, Success, Try}
import scala.util.control.NonFatal
import java.io.{
PrintWriter, StringWriter}
import java.util.UUID
2. 创建一个 Instrumentation 对象并使用其方法记录信息。
val instrumentation = new Instrumentation()
// 记录流水线阶段信息
val stage = new PipelineStage()
instrumentation.logPipelineStage(stage)
// 记录数据集信息
val dataset: Dataset[_] = ...
instrumentation.logDataset(dataset)
// 记录参数值
val param1: Param[String] = ...
val param2