我目前正在尝试在火花流中实施两阶段流程。首先,我打开一个kafkaStream,使用auto.offset.reset=earliest
读取主题中已有的所有内容并在其上训练我的模型。
我使用了一个流,因为我无法在不打开流之前找到如何做到(Spark - Get earliest and latest offset of Kafka without opening stream)。
由于我没有发现在不停止整个StreamingContext的情况下停止流的方法,因此在使用ssc.stop(true, true)
进行模型计算后停止上下文。
当我现在尝试创建一个新的StreamingContext(使用旧的sparkConfig或具有相同参数的新的)时,调用我的方法用新的groupId和auto.offset.reset=latest
打开一个新的KafkaStream它看起来像是当我向Kafka主题写新内容时,根本没有流式传输。 forEachRDD中的print()和count()以及println都不会在我的IDE中产生任何输出。
应用程序的结构如下:
def main(args: Array[String]) {
val sparkConf = new SparkConf().setAppName(sparkAppName).setMaster(sparkMaster)
.set("spark.local.dir", sparkLocalDir)
.set("spark.driver.allowMultipleContexts", "true")
sparkConf.registerKryoClasses(Array(classOf[Span]))
sparkConf.registerKryoClasses(Array(classOf[Spans]))
sparkConf.registerKryoClasses(Array(classOf[java.util.Map[String, String]]))
val trainingSsc = new StreamingContext(sparkConf, Seconds(batchInterval))
trainingSsc.checkpoint(checkpoint)
//val predictor = (model, ninetynine, median, avg, max)
val result = trainKMeans(trainingSsc);
trainingSsc.stop(true, false)
val predictionSsc = new StreamingContext(sparkConf, Seconds(batchInterval))
val threshold = result._5
val model = result._1
kMeansAnomalyDetection(predictionSsc, model, threshold)
}
我希望你能指出我犯的错误 - 如果你需要进一步的细节,请告诉我。任何帮助和提示都非常感谢。
答案 0 :(得分:2)
一般来说,该计划看起来正朝着正确的方向前进,但有几点需要修复:
Spark Streaming将在发出streamingContext.start()
时启动流式调度程序。 DStream操作只能由调度程序执行。这意味着对这两个调用进行排序将不会产生任何结果:
val result = trainKMeans(trainingSsc);
trainingSsc.stop(true, false)
在进行任何培训之前,将停止流媒体上下文。
相反,我们应该这样做:
val result = trainKMeans(trainingSsc)
trainingSsc.foreachRDD{_ => trainingSsc.stop(false, false) } // note that we don't stop the spark context here
trainingSsc.start()
trainingSsc.awaitTermination()
在这种情况下,我们开始流式传输过程;我们让第一个间隔执行,我们的模型将被训练,然后我们停止处理。
第二个流应该在与第一个不同的组上启动(kafka流创建未显示在代码段中)
对于第二个流媒体上下文,我们错过了一个开始:
val predictionSsc = new StreamingContext(sparkContext, Seconds(batchInterval)) // note that we pass a sparkContext here, not a config. We reuse the same spark context.
val threshold = result._5
val model = result._1
kMeansAnomalyDetection(predictionSsc, model, threshold)
predictionSsc.start()
predictionSsc.awaitTermination()
此时我们应该有一个工作流。