簡體   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