Apache Spark 2.2で最新の構造化ストリーミングを使用していますが、次の例外が発生しました。
org.Apache.spark.sql.AnalysisException:ストリーミングDataFrames/Datasetsにストリーミング集約がない場合、完全な出力モードはサポートされません;;
完全出力モードでストリーミング集約が必要なのはなぜですか? Sparkがストリーミングクエリで集計なしの完全な出力モードを許可した場合はどうなりますか?
scala> spark.version
res0: String = 2.2.0
import org.Apache.spark.sql.execution.streaming.MemoryStream
import org.Apache.spark.sql.SQLContext
implicit val sqlContext: SQLContext = spark.sqlContext
val source = MemoryStream[(Int, Int)]
val ids = source.toDS.toDF("time", "id").
withColumn("time", $"time" cast "timestamp"). // <-- convert time column from Int to Timestamp
dropDuplicates("id").
withColumn("time", $"time" cast "long") // <-- convert time column back from Timestamp to Int
import org.Apache.spark.sql.streaming.{OutputMode, Trigger}
import scala.concurrent.duration._
scala> val q = ids.
| writeStream.
| format("memory").
| queryName("dups").
| outputMode(OutputMode.Complete). // <-- memory sink supports checkpointing for Complete output mode only
| trigger(Trigger.ProcessingTime(30.seconds)).
| option("checkpointLocation", "checkpoint-dir"). // <-- use checkpointing to save state between restarts
| start
org.Apache.spark.sql.AnalysisException: Complete output mode not supported when there are no streaming aggregations on streaming DataFrames/Datasets;;
Project [cast(time#10 as bigint) AS time#15L, id#6]
+- Deduplicate [id#6], true
+- Project [cast(time#5 as timestamp) AS time#10, id#6]
+- Project [_1#2 AS time#5, _2#3 AS id#6]
+- StreamingExecutionRelation MemoryStream[_1#2,_2#3], [_1#2, _2#3]
at org.Apache.spark.sql.catalyst.analysis.UnsupportedOperationChecker$.org$Apache$spark$sql$catalyst$analysis$UnsupportedOperationChecker$$throwError(UnsupportedOperationChecker.scala:297)
at org.Apache.spark.sql.catalyst.analysis.UnsupportedOperationChecker$.checkForStreaming(UnsupportedOperationChecker.scala:115)
at org.Apache.spark.sql.streaming.StreamingQueryManager.createQuery(StreamingQueryManager.scala:232)
at org.Apache.spark.sql.streaming.StreamingQueryManager.startQuery(StreamingQueryManager.scala:278)
at org.Apache.spark.sql.streaming.DataStreamWriter.start(DataStreamWriter.scala:247)
... 57 elided
構造化ストリーミングプログラミングガイド -その他のクエリ(集計、mapGroupsWithState
およびflatMapGroupsWithState
を除く)から:
集計されていないすべてのデータを結果テーブルに保持することは不可能であるため、完全モードはサポートされていません。
質問に答えるには:
Sparkがストリーミングクエリで集計なしの完全な出力モードを許可した場合はどうなりますか?
おそらくOOM。
不可解な部分は、dropDuplicates("id")
が集約としてマークされていない理由です。
問題は出力モードだと思います。 OutputMode.Completeを使用する代わりに、以下に示すようにOutputMode.Appendを使用します。
scala> val q = ids
.writeStream
.format("memory")
.queryName("dups")
.outputMode(OutputMode.Append)
.trigger(Trigger.ProcessingTime(30.seconds))
.option("checkpointLocation", "checkpoint-dir")
.start