Apache spark 为什么流数据集的foreachPartition会出错?
我正在从Spark流媒体迁移到结构化流媒体,我面临以下代码的问题:Apache spark 为什么流数据集的foreachPartition会出错?,apache-spark,apache-spark-sql,spark-structured-streaming,Apache Spark,Apache Spark Sql,Spark Structured Streaming,我正在从Spark流媒体迁移到结构化流媒体,我面临以下代码的问题: def processDataSet(inputDataset:Dataset[MyMessage],foobar:foobar)={ inputDataset.foreachPartition{partitionIterator=> val filteredIterator=partitionIterator.filter(foobar.filter) ... ... } } val streamingQuery
def processDataSet(inputDataset:Dataset[MyMessage],foobar:foobar)={
inputDataset.foreachPartition{partitionIterator=>
val filteredIterator=partitionIterator.filter(foobar.filter)
...
...
}
}
val streamingQuery=inputDataset
.writeStream
.触发器(处理时间(“5秒”))
.outputMode(“追加”)
.格式(“控制台”)
开始
它会出现以下错误AnalysisException
:
原因:org.apache.spark.sql.AnalysisException:具有流媒体源的查询必须使用writeStream.start()执行
流式查询是否不支持foreachPartition
?在这种情况下,writeStream.foreach
是实现foreachPartition
的唯一方法吗
我希望避免在每次事件发生时发送事件,而是累积所有行,形成一个庞大的POST请求主体,并将其发送到HTTP端点。因此,如果一个批处理中有1000个事件和5个分区,那么在每个请求主体中并行生成5个请求和200个事件。TL;DR是的<代码>foreachPartition操作不受支持,您应该改用 引用scaladoc的: foreachPartition(f:(迭代器[T])⇒ Unit):Unit将函数
f
应用于此数据集的每个分区
您现在可能已经发现,foreach
是一个动作,因此会触发Spark执行
由于您使用的是流式数据集,因此不允许使用“传统”方法(如foreach
)触发它们的执行
引用结构化流媒体:
此外,有些数据集方法在流式数据集上不起作用。这些操作将立即运行查询并返回结果,这在流数据集上没有意义。相反,这些功能可以通过显式启动流式查询来实现(请参阅下一节)
流媒体备选方案包括foreach
运营商(又称sink)。这就是如何在结构化流媒体中进行foreachPartition
引述:
foreach操作允许对输出数据计算任意操作
要使用它,您必须实现接口ForeachWriter
,该接口具有在触发器后生成输出行序列时调用的方法
我希望避免在每次事件发生时发送事件,而是累积所有行,形成一个庞大的POST请求主体,并将其发送到HTTP端点。因此,如果一个批处理中有1000个事件和5个分区,那么在每个请求体中并行生成5个请求和200个事件 这看起来像是将数据集写入接收器之前的聚合,不是吗?使用
groupBy
运算符和collect\u list
函数对行进行分组,这样当您writeStream
时,您可以拥有任意数量的组
除非没有其他方法,否则我宁愿避免使用RDD的低级功能分区来优化写操作。我有这样一个要求:foreachPartition(迭代器->一次性从迭代器收集该分区的所有内容->对其进行处理。是否有方法收集该分区的所有事件?我认为foreach接收器不允许-->