如何在start()之前执行操作?

时间:2017-10-13 16:46:20

标签: scala apache-spark spark-structured-streaming

我正在开发一个火花流媒体作业(使用不使用DStreams的结构化流媒体)。我从kafka收到一条消息,其中包含许多带逗号分隔值的字段,其中第一列是文件名。现在基于该文件名,我将不得不从HDFS读取文件并创建数据帧并进一步操作。这似乎很简单,但是火花不允许我在调用start之前运行任何动作。 Spark Documentation也引用了相同的内容。

  

此外,还有一些数据集方法无法使用   流数据集。它们是立即运行查询的操作   并返回结果,这对流式数据集没有意义。

以下是我的尝试。

object StructuredStreamingExample {
  case class filenameonly(value:String)
  def main(args:Array[String])
  {
    val spark = SparkSession.builder.appName("StructuredNetworkWordCount").master("local[*]").getOrCreate()

    spark.sqlContext.setConf("spark.sql.shuffle.partitions", "5")

    import spark.implicits._
    val lines = spark
      .readStream
      .format("kafka")
      .option("kafka.bootstrap.servers", "localhost:9092")
      .option("subscribe", "strtest")
      .load()
   val values=lines.selectExpr("CAST(value AS STRING)").as[String]
   val filename = values.map(x => x.split(",")(0)).toDF().select($"value")
   //Here how do i convert the filename which is a Dataframe to string and apply that to spark.readtextfile(filename)
   datareadfromhdfs
  .writeStream
  .trigger(ProcessingTime("10 seconds"))
  .outputMode("append")
  .format("console")
  .start()
  .awaitTermination()

现在在上面的代码中,我得到的文件名是一个Dataframe,如何将其转换为String,以便我可以执行spark.readtextfile(filename)来读取HDFS中的文件。

2 个答案:

答案 0 :(得分:0)

我不确定它是否能最好地用于火花流,但在这种情况下,我会调用filename.foreachRDD并从那里读取hdfs文件并执行您需要的任何操作。 (请记住,在foreachRDD中运行时,您不能使用全局spark会话,但需要从构建器中获取或者创建它:val sparkSession = SparkSession.builder.config(myCurrentForeachRDD.sparkContext.getConf).getOrCreate()

您似乎依赖于流来告诉您在哪里查看和加载文件。您是否尝试过在该文件夹上使用文件流并让spark自动监视并自动读取新文件?

答案 1 :(得分:0)

使用spark结构化流媒体肯定不是最好的用例。如果您正确理解了spark结构化流,那么所有数据转换/聚合都应该在生成结果表的查询上进行。但是,您仍然可以实现一些解决方法,您可以编写代码以从(falt)mapWithGroupState中的HDFS读取数据。但是,同样不建议这样做。

相关问题