繁体   English   中英

Spark流式自定义指标

[英]Spark streaming custom metrics

我正在开发一个Spark Streaming程序,它检索Kafka流,对流进行非常基本的转换,然后将数据插入到DB(如果相关则为voltdb)。 我正在尝试测量向DB插入行的速率。 我认为指标很有用(使用JMX)。 但是我找不到如何向Spark添加自定义指标。 我查看了Spark的源代码并找到了这个帖子,但它对我不起作用。 我还在conf.metrics文件中启用了JMX接收器。 什么不起作用我没有看到我的自定义指标与JConsole。

有人可以解释如何添加自定义指标(最好通过JMX)来激发流媒体? 或者如何测量我的数据库(特别是VoltDB)的插入速率? 我在Java 8中使用spark。

在挖掘源代码后,我发现如何添加自己的自定义指标。 它需要3件事:

  1. 创建我自己的自定义 有点像这样
  2. 在spark metrics.properties文件中启用Jmx接收器。 我使用的具体行是: *.sink.jmx.class=org.apache.spark.metrics.sink.JmxSink ,为所有实例启用JmxSink
  3. 在SparkEnv指标系统中注册我的自定义源。 这里可以看到一个如何操作的例子 - 我之前实际上看过这个链接但错过了注册部分,这使我无法在JVisualVM中实际看到我的自定义指标

我仍在苦苦思索如何实际计算插入VoltDB的次数,因为代码在执行程序上运行,但这是一个不同主题的主题:)

我希望这会有助于其他人

Groupon有一个名为spark-metrics的库,它允许您在执行程序上使用一个简单的(类似Codahale)API,并将结果整理回驱动程序中,并自动在Spark的现有指标注册表中注册。 然后,当您根据Spark文档配置度量标准接收器时,这些会自动与Spark的内置指标一起导出。

从VoltDB插入基于插入的行,使用累加器 - 然后从您的驱动程序中创建一个监听器 - 也许这样就可以让你开始

sparkContext.addSparkListener(new SparkListener() {
  override def onStageCompleted(stageCompleted: SparkListenerStageCompleted) {
    stageCompleted.stageInfo.accumulables.foreach { case (_, acc) => {

在这里你可以访问那些行组合累加器,然后你可以发送到你的接收器..

这是一个很好的教程,涵盖了使用Graphite设置Spark的MetricsSystem所需的所有设置。 这应该够了吧:

http://www.hammerlab.org/2015/02/27/monitoring-spark-with-graphite-and-grafana/

下面是Java中的一个工作示例。
它使用StreaminQuery进行测试(不幸的是, StreaminQuery没有像StreamingContext直到Spark 2.3.1之类的ootb指标)。

脚步:

Source类的同一个包中定义自定义源

package org.apache.spark.metrics.source;

import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
import lombok.Data;
import lombok.experimental.Accessors;
import org.apache.spark.sql.streaming.StreamingQueryProgress;

/**
 * Metrics source for structured streaming query.
 */
public class StreamingQuerySource implements Source {
    private String appName;
    private MetricRegistry metricRegistry = new MetricRegistry();
    private final Progress progress = new Progress();

    public StreamingQuerySource(String appName) {
        this.appName = appName;
        registerGuage("batchId", () -> progress.batchId());
        registerGuage("numInputRows", () -> progress.numInputRows());
        registerGuage("inputRowsPerSecond", () -> progress.inputRowsPerSecond());
        registerGuage("processedRowsPerSecond", () -> progress.processedRowsPerSecond());
    }

    private <T> Gauge<T> registerGuage(String name, Gauge<T> metric) {
        return metricRegistry.register(MetricRegistry.name(name), metric);
    }

    @Override
    public String sourceName() {
        return String.format("%s.streaming", appName);
    }


    @Override
    public MetricRegistry metricRegistry() {
        return metricRegistry;
    }

    public void updateProgress(StreamingQueryProgress queryProgress) {
        progress.batchId(queryProgress.batchId())
                .numInputRows(queryProgress.numInputRows())
                .inputRowsPerSecond(queryProgress.inputRowsPerSecond())
                .processedRowsPerSecond(queryProgress.processedRowsPerSecond());
    }

    @Data
    @Accessors(fluent = true)
    private static class Progress {
        private long batchId = -1;
        private long numInputRows = 0;
        private double inputRowsPerSecond = 0;
        private double processedRowsPerSecond = 0;
    }
}

创建SparkContext后立即注册源

    querySource = new StreamingQuerySource(getSparkSession().sparkContext().appName());
    SparkEnv.get().metricsSystem().registerSource(querySource);

更新StreamingQueryListener.onProgress(event)中的数据

  querySource.updateProgress(event.progress());

配置metrics.properties

*.sink.graphite.class=org.apache.spark.metrics.sink.GraphiteSink
*.sink.graphite.host=xxx
*.sink.graphite.port=9109
*.sink.graphite.period=10
*.sink.graphite.unit=seconds

# Enable jvm source for instance master, worker, driver and executor
master.source.jvm.class=org.apache.spark.metrics.source.JvmSource
worker.source.jvm.class=org.apache.spark.metrics.source.JvmSource
driver.source.jvm.class=org.apache.spark.metrics.source.JvmSource
executor.source.jvm.class=org.apache.spark.metrics.source.JvmSource

石墨输出器中的示例输出(映射到prometheus格式)

streaming_query{application="local-1538032184639",model="model1",qty="batchId"} 38
streaming_query{application="local-1538032184639",model="model1r",qty="inputRowsPerSecond"} 2.5
streaming_query{application="local-1538032184639",model="model1",qty="numInputRows"} 5
streaming_query{application="local-1538032184639",model=model1",qty="processedRowsPerSecond"} 0.81

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM