重构累加器obj并在Spark Driver中读取其值

时间:2018-03-08 11:45:18

标签: java apache-spark spark-streaming

我遇到一个问题,我在计算火花流媒体作业中发生的错误数量,并且必须围绕它创建指标。

但我想在sparkdriver中编写度量创建逻辑,以便为整个spark工作创建指标。

我想到的方法是创建一个累加器,并在我得到错误时立即递增它。

现在我将编写一个sparkListener并将accumlator值用于generte指标。

所以问题是我无法从监听器中读取累加器的值,因为它是一个不同的类。

我们可以使用sparkConstruct在spark中重建一个累加器,这样我们就可以在不同的组件中使用相同的累加器。

1 个答案:

答案 0 :(得分:0)

我无法找到任何从Spark Context重建累加器的正确方法,但得到了一个解决方案,我可以在Spark Driver上读取命名累加器的值。为此,我们需要扩展SparkListener并覆盖 onStageCompleted ,如下所示。然后我们就可以访问该特定驱动程序中的所有累加器。

以下是示例代码:

主要方法

public static void main(String[] args) {
    final LongAccumulator acc;

    String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
    System.out.println(date);
    try {

        JavaSparkContext js = new JavaSparkContext("local[*]", "spark16");
        JavaStreamingContext jsc = new JavaStreamingContext(js, Durations.seconds(5));
        AccListener accList = new AccListener();
        acc = jsc.ssc().sc().longAccumulator("testStream");
        **jsc.sparkContext().sc().addSparkListener(accList);**
        JavaReceiverInputDStream<String> lines = jsc.socketTextStream("localhost", 12345);
        JavaDStream<String> ds = lines.map(new Function<String, String>() {
            private static final long serialVersionUID = 1L;

            public String call(String arg0) throws Exception {
                System.out.println("Inside map: " + arg0);
                acc.add(1L);
                Thread.sleep(300);
                return arg0;
            }
        });
        ds.print();

        jsc.start();
        jsc.awaitTermination();
        jsc.close();
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {

    }
}

<强> AccListener.java

class AccListener extends SparkListener {

@Override
public void onStageCompleted(SparkListenerStageCompleted stageCompleted) {
    super.onStageCompleted(stageCompleted);
    scala.collection.mutable.HashMap<Object, AccumulableInfo> map = stageCompleted.stageInfo().accumulables();
    Collection<Tuple2<Object, AccumulableInfo>> newMap = JavaConversions.asJavaCollection(map);
    System.out.println("onStageCompleted");
    for (Tuple2<Object, AccumulableInfo> t : newMap) {

        if (t._2.name().get().equalsIgnoreCase("testStream")) {
            System.out.println(t._1 + "    " + t._2.name().get() + "   " + t._2.value().get().toString());
        }
    }
   }
  }

参考https://gist.github.com/squito/2f7cc02c313e4c9e7df4