我有下表:
DEST_COUNTRY_NAME ORIGIN_COUNTRY_NAME count
United States Romania 15
United States Croatia 1
United States Ireland 344
Egypt United States 15
表表示为数据集。
scala> dataDS
res187: org.apache.spark.sql.Dataset[FlightData] = [DEST_COUNTRY_NAME: string, ORIGIN_COUNTRY_NAME: string ... 1 more field]
我能够按批处理方式对条目进行排序。
scala> dataDS.sort(col("count")).show(100);
我现在想尝试是否可以使用流媒体执行相同的操作。为此,我想必须将文件作为流读取。
scala> val staticSchema = dataDS.schema;
staticSchema: org.apache.spark.sql.types.StructType = StructType(StructField(DEST_COUNTRY_NAME,StringType,true), StructField(ORIGIN_COUNTRY_NAME,StringType,true), StructField(count,IntegerType,true))
scala> val dataStream = spark.
| readStream.
| schema(staticSchema).
| option("header","true").
| csv("data/flight-data/csv/2015-summary.csv");
dataStream: org.apache.spark.sql.DataFrame = [DEST_COUNTRY_NAME: string, ORIGIN_COUNTRY_NAME: string ... 1 more field]
scala> dataStream.isStreaming;
res245: Boolean = true
但是我无法进一步进步如何以流形式读取数据。
我已经执行了sort
转换`过程
scala> dataStream.sort(col("count"));
res246: org.apache.spark.sql.Dataset[org.apache.spark.sql.Row] = [DEST_COUNTRY_NAME: string, ORIGIN_COUNTRY_NAME: string ... 1 more field]
我想现在我应该使用Dataset
的{{1}}方法。我运行了以下两个命令,但都返回了错误。
writeStream
还有这个
scala> dataStream.sort(col("count")).writeStream.
| format("memory").
| queryName("sorted_data").
| outputMode("complete").
| start();
org.apache.spark.sql.AnalysisException: Complete output mode not supported when there are no streaming aggregations on streaming DataFrames/Datasets;;
从错误中看来,我应该聚合(组)数据,但是我认为不需要这样做,因为我可以将任何批处理操作作为流运行。
我如何理解如何对作为流到达的数据进行排序?
答案 0 :(得分:1)
不幸的是,错误消息告诉您的内容是准确的。
您提出的观点:
但是我认为我不需要这样做,因为我可以将任何批处理操作作为流运行。
并非没有优点,但它错过了一个基本点,即结构化流并非与微批处理紧密相关。
一个人很容易想到一些无法扩展的骇客
import org.apache.spark.sql.functions._
dataStream
.withColumn("time", window(current_timestamp, "5 minute")) // Some time window
.withWatermark("time", "0 seconds") // Immediate watermark
.groupBy("time")
.agg(sort_array(collect_list(struct($"count", $"DEST_COUNTRY_NAME", $"ORIGIN_COUNTRY_NAME"))).as("data"))
.withColumn("data", explode($"data"))
.select($"data.*")
.select(df.columns.map(col): _*)
.writeStream
.outputMode("append")
...
.start()