必须使用writeStream.start()执行带有流源的查询;

时间:2016-11-15 12:22:53

标签: scala spark-streaming spark-dataframe

我正试图在spark中读取来自kafka(版本10)的消息并尝试打印它。

     import spark.implicits._

         val spark = SparkSession
              .builder
              .appName("StructuredNetworkWordCount")
              .config("spark.master", "local")
              .getOrCreate()  

            val ds1 = spark.readStream.format("kafka")
    .option("kafka.bootstrap.servers", "localhost:9092")  
.option("subscribe", "topicA")  .load()
          ds1.collect.foreach(println)
         ds1.writeStream
           .format("console")
           .start()
          ds1.printSchema()

获取错误线程“main”中的异常

  

org.apache.spark.sql.AnalysisException:使用流媒体源查询   必须使用writeStream.start();;

执行

5 个答案:

答案 0 :(得分:10)

您正在分支查询计划:来自您尝试的相同ds1:

  • ds1.collect.foreach(...)
  • ds1.writeStream.format(...){...}

但是你只是在第二个分支上调用.start(),而另一个没有终止而留下另一个终止,这反过来会抛出你要回来的异常。

解决方案是启动两个分支并等待终止。

val ds1 = spark.readStream.format("kafka")
  .option("kafka.bootstrap.servers", "localhost:9092")  
  .option("subscribe", "topicA")  
  .load()
val query1 = ds1.collect.foreach(println)
  .writeStream
  .format("console")
  .start()
val query2 = ds1.writeStream
  .format("console")
  .start()

ds1.printSchema()
query1.awaitTermination()
query2.awaitTermination()

答案 1 :(得分:4)

我通过使用以下代码解决了问题。

 val df = session
  .readStream
  .format("kafka")
  .option("kafka.bootstrap.servers", brokers)
  .option("subscribe", "streamTest2")
  .load();

    val query = df.writeStream
  .outputMode("append")
  .format("console")
  .start()
query.awaitTermination()

答案 2 :(得分:3)

我在这个问题上苦苦挣扎。我尝试了各种博客提供的建议解决方案。 但我的情况是,在查询中调用start()到最后我最终导致此问题的调用awaitTerminate()函数之间没有什么声明。

请以这种方式尝试,这对我来说非常有用。 工作示例:

val query = df.writeStream
      .outputMode("append")
      .format("console")
      .start().awaitTermination();

如果以这种方式编写将导致异常/错误:

val query = df.writeStream
      .outputMode("append")
      .format("console")
      .start()

    // some statement 
    // some statement 

    query.awaitTermination();

将抛出给定异常并关闭流驱动程序。

答案 3 :(得分:1)

请删除ds1.collect.foreach(println)ds1.printSchema(),并使用outputModeawaitAnyTermination进行后台处理,等待相关的spark.streams上的任何查询终止

val spark = SparkSession
    .builder
    .appName("StructuredNetworkWordCount")
    .config("spark.master", "local[*]")
    .getOrCreate()

  val ds1 = spark.readStream.format("kafka")
    .option("kafka.bootstrap.servers", "localhost:9092")
    .option("subscribe", "topicA")  .load()

  val consoleOutput1 = ds1.writeStream
     .outputMode("update")
     .format("console")
     .start()

  spark.streams.awaitAnyTermination()

|key|value|topic|partition|offset|
+---+-----+-----+---------+------+
+---+-----+-----+---------+------+

答案 4 :(得分:0)

我能够通过以下代码解决此问题。在我的场景中,我有多个中间数据帧,它们基本上是在inputDF上进行的转换。

 val query = joinedDF
      .writeStream
      .format("console")
      .option("truncate", "false")
      .outputMode(OutputMode.Complete())
      .start()
      .awaitTermination()

joinedDF是上一次执行转换的结果。