Scala Spark结构化流数据帧上的排序操作

Scala Spark结构化流数据帧上的排序操作,scala,apache-spark,spark-structured-streaming,Scala,Apache Spark,Spark Structured Streaming,我正在spark structured streaming dataframe上尝试一个非常简单的排序操作,但结果是“线程中的异常”org.apache.spark.sql.AnalysisException:流式数据帧/数据集上不支持排序,除非它在聚合数据帧/数据集上处于完全输出模式”,并出现以下异常。你能帮我一下吗 代码: val df: DataFrame = spark.readStream.format("kafka") .option("kafka.bootst

我正在spark structured streaming dataframe上尝试一个非常简单的排序操作,但结果是“线程中的异常”org.apache.spark.sql.AnalysisException:流式数据帧/数据集上不支持排序,除非它在聚合数据帧/数据集上处于完全输出模式”,并出现以下异常。你能帮我一下吗

代码

   val df: DataFrame = spark.readStream.format("kafka")
        .option("kafka.bootstrap.servers", kafkaBrokerList)
        .option("kafka.security.protocol", security)
        .option("startingOffsets", "latest")
        .option("subscribe", srcTopic)
        .option("group.id", groupID)
        .option("failOnDataLoss", false)        
        .load

      val uDF = df
        .selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
        .as[(String, String)]
        .select($"value")
        .select(from_json($"value", uSchema).as("events"))
        .select($"events.*")

     val uDF2 = uDF
        .select($"COL1", $"COL2", $"COL3", $"COL4", $"COL5", $"COL6", $"COL7", $"COL8")
        .sort($"COL5",$"COL3",$"COL8")


    val kDF = uDF2
        .writeStream
        .format("kafka")
        .option("kafka.bootstrap.servers", "localhost:9092")
        .option("kafka.security.protocol", "PLAINTEXT")
        .option("topic", "r_topic")
        .option("checkpointLocation", "/tmp/kafka-sink-checkpoint")
        .start()


    kDF.awaitTermination()
例外情况:

Exception in thread "main" org.apache.spark.sql.AnalysisException: Sorting is not supported on streaming DataFrames/Datasets, unless it is on aggregated DataFrame/Dataset in Complete output mode;;
数据:

Exception in thread "main" org.apache.spark.sql.AnalysisException: Sorting is not supported on streaming DataFrames/Datasets, unless it is on aggregated DataFrame/Dataset in Complete output mode;;
要按“COL5”、“COL3”、“COL8”对DF进行排序


您可能需要重新考虑流中的排序输出。在真正的流中,您永远不会得到输出,因为从理论上讲,您不太可能遇到流中的最后一个事件。虽然Spark实际上进行微批量处理,但它试图保持语义与真正的流式处理相似。您可能最终会重新定义您的问题,并利用有状态操作,如windowing或flatMapGroupsWithState。您还可以手动拆分范围并运行批处理。

您需要在排序(排序依据)之前按操作分组,如:

uDF.select($"COL1", $"COL2", $"COL3", $"COL4", $"COL5", $"COL6", $"COL7", $"COL8")
   .groupBy("COL1")
   .agg(max("COL2").as("COL2")......).sort("........")