在Spark流中的每个微批处理之后调用java函数

时间:2017-09-22 13:18:54

标签: apache-spark spark-streaming

以下简单程序从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();
}

1 个答案:

答案 0 :(得分:0)

你应该能够通过以下方式实现这一目标:

kafkaDataStreamReader.map{value -> mySideEffect(); value}

每次从kafka收到微型分析时,这将调用函数mySideEffect,我怎么不建议这样做,更好的方法是观看你持久保存CSV的文件夹或者只是检查网页ui,考虑到微批次最多每隔几秒发生一次,你就会被电子邮件淹没。如果你想确保流媒体应用程序已启动,你可以每隔几秒查询一次spark REST API并确保它仍然存在 https://spark.apache.org/docs/latest/monitoring.html