Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在spark结构化流式foreachBatch方法中实现聚合?_Java_Apache Spark_Apache Spark Sql_Spark Streaming_Spark Structured Streaming - Fatal编程技术网

Java 如何在spark结构化流式foreachBatch方法中实现聚合?

Java 如何在spark结构化流式foreachBatch方法中实现聚合?,java,apache-spark,apache-spark-sql,spark-streaming,spark-structured-streaming,Java,Apache Spark,Apache Spark Sql,Spark Streaming,Spark Structured Streaming,我有一个用例 我需要从数据源读取记录并将其写入多个接收器,包括kafka,以及一些聚合 下面是我的伪代码的样子 Dataset<Row> dataset = spark.readStream()...... dataset.writeStream().foreachBatch( // do some processing, including aggregations // write it to multiple sinks batch.write().format('kafka

我有一个用例

我需要从数据源读取记录并将其写入多个接收器,包括kafka,以及一些聚合

下面是我的伪代码的样子

Dataset<Row> dataset = spark.readStream()......

dataset.writeStream().foreachBatch(
// do some processing, including aggregations
// write it to multiple sinks
batch.write().format('kafka').save();
).start().awaitTermination();
Dataset数据集=spark.readStream()。。。。。。
dataset.writeStream().foreachBatch(
//进行一些处理,包括聚合
//将其写入多个接收器
batch.write().format('kafka').save();
).start()等待终止();
当我在foreach中尝试某种聚合方法时,默认情况下它采用append模式并删除旧的聚合。因此,输出仅包含当前批次的结果

我的要求是,当第二批数据到达时,它应该与第一批数据的结果合并

例如:对于查询,
dataset.groupBy(“id”).count(value)

如果第一批输入为:{“id”:1,“value”:1},{“id”:1,“value”:1}

输出:{“id”:1,“值”:“2”}

第二批输入: {“id”:1,“value”:3},{“id”:1,“value”:2}

输出:{“id”:1,“value”:5}

预期输出:{“id”:1,“value”:7}

如何在spark中实现这一点


提前感谢。

以上示例是一个数据流示例,而不是结构化流。您需要将Spark结构化流视为将数据加载到无界表中

假设数据源是kafka,下面是结构化流的一个基本示例。请注意,ReadStream和WriteStream Api无法进行模式推断。模式需要来自数据源连接器,在本例中是Kafka

val df = sparkSession
  .readStream
  .format("kafka")
  .option("kafka.bootstrap.servers", "localhost:9031")
  .option("subscribe", "word-count")
  .option("startingOffsets", "latest")
  .option("failOnDataLoss", "false")
  .load()

val query = df
  .selectExpr("CAST(key AS STRING) as key", "CAST(value AS STRING) as value")
  .as[(String, String)]
  .select(from_json($"value", schema = schema).as("data"))
  .writeStream
  .format("parquet")
  .option("path", "/parquet/word-count/")
  .option("checkpointLocation", "/tmp/word-count-chkpnt")
  .trigger(ProcessingTime("10 second"))
  .outputMode(OutputMode.Append())
  .start()
使用.trigger()函数创建微批次,并使用outputMode保存每个微批次的结果。在本例中,我每10秒创建一个微批,
.trigger(ProcessingTime(“10秒”))
并将流中的每个事件作为一行附加到拼花地板文件
.outputMode(outputMode.Append())

在您的情况下,需要使用.trigger()和您选择的微批处理间隔以及
.outputMode(outputMode.Update())
来插入具有值的新键或使用递增值更新现有键

下面是聚合逻辑的发展方向。您可以将聚合逻辑分解为单独的数据帧,并将数据帧作为流而不是链接写入 为了可读性

.selectExpr("CAST(key AS STRING) as key", "CAST(value AS STRING) as value")
  .as[(String, String)]
  .select(from_json($"value", schema = schema).as("data"))

结构化流媒体。

感谢您抽出时间发布此消息。但我的用例有点不同,我需要以有效的方式将处理后的数据写入多个接收器,因此我将继续使用foreachbatch。我需要知道如何在到达foreach batch.check内部的微批次数据集上实现更新模式