以下简单程序从kafka流中读取并每隔5分钟写入CSV文件及其火花流。有没有办法可以在“DRIVER PROGRAM”(不在执行程序中)中进行微批处理后调用Java函数。
我同意在流中调用任意代码不是一个好习惯,但这是特殊情况,我们的数据量很小。请adivse。感谢。
public static void main(String[] args) throws Exception {
if (args.length == 0)
throw new Exception("Usage program configFilename");
String configFilename = args[0];
addShutdownHook();
ConfigLoader.loadConfig(configFilename);
sparkSession = SparkSession
.builder()
.appName(TestKafka.class.getName())
.master(ConfigLoader.getValue("master")).getOrCreate();
SparkContext context = sparkSession.sparkContext();
context.setLogLevel(ConfigLoader.getValue("logLevel"));
SQLContext sqlCtx = sparkSession.sqlContext();
System.out.println("Spark context established");
DataStreamReader kafkaDataStreamReader = sparkSession.readStream()
.format("kafka")
.option("kafka.bootstrap.servers", ConfigLoader.getValue("brokers"))
.option("group.id", ConfigLoader.getValue("groupId"))
.option("subscribe", ConfigLoader.getValue("topics"))
.option("failOnDataLoss", false);
Dataset<Row> rawDataSet = kafkaDataStreamReader.load();
rawDataSet.printSchema();
rawDataSet.createOrReplaceTempView("rawEventView1");
rawDataSet = rawDataSet.withColumn("rawEventValue", rawDataSet.col("value").cast("string"));
rawDataSet.printSchema();
rawDataSet.createOrReplaceTempView("eventView1");
sqlCtx.sql("select * from eventView1")
.writeStream()
.format("csv")
.option("header", "true")
.option("delimiter", "~")
.option("checkpointLocation", ConfigLoader.getValue("checkpointPath"))
.option("path", ConfigLoader.getValue("recordsPath"))
.outputMode(OutputMode.Append())
.trigger(ProcessingTime.create(Integer.parseInt(ConfigLoader.getValue("kafkaProcessingTime"))
, TimeUnit.SECONDS))
.start()
.awaitTermination();
}
答案 0 :(得分:0)
你应该能够通过以下方式实现这一目标:
kafkaDataStreamReader.map{value -> mySideEffect(); value}
每次从kafka收到微型分析时,这将调用函数mySideEffect
,我怎么不建议这样做,更好的方法是观看你持久保存CSV的文件夹或者只是检查网页ui,考虑到微批次最多每隔几秒发生一次,你就会被电子邮件淹没。如果你想确保流媒体应用程序已启动,你可以每隔几秒查询一次spark REST API并确保它仍然存在
https://spark.apache.org/docs/latest/monitoring.html