我遇到一个问题,我在计算火花流媒体作业中发生的错误数量,并且必须围绕它创建指标。
但我想在sparkdriver中编写度量创建逻辑,以便为整个spark工作创建指标。
我想到的方法是创建一个累加器,并在我得到错误时立即递增它。
现在我将编写一个sparkListener并将accumlator值用于generte指标。
所以问题是我无法从监听器中读取累加器的值,因为它是一个不同的类。
我们可以使用sparkConstruct在spark中重建一个累加器,这样我们就可以在不同的组件中使用相同的累加器。
答案 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());
}
}
}
}