【问题标题】:Capture and write string inside of dataframe using foreach row使用 foreach 行在数据帧内捕获和写入字符串
【发布时间】:2019-05-29 16:48:00
【问题描述】:

在使用 Scala.但由于它部署在集群上,无法捕获任何记录。任何人都可以提供解决方案吗?

假设 TEST_DB.finalresult 有 2 个字段 input1 和 input2:

val finalresult=spark.sql("select * from TEST_DB.finalresult")

finalResult.foreach { row => 
    val param1=row.getAs("input1").asInstanceOf[String]
    val param2=row.getAs("input2").asInstanceOf[String]

    val string = """new values of param1 and param2 are -> """ + param1 + """,""" + param2
    // how to append modified string to csv file continously for each microbatch in hdfs ??
}

【问题讨论】:

    标签: scala apache-spark hadoop apache-spark-sql


    【解决方案1】:

    在您的代码中,您创建了想要的 string 变量,但它没有保存在任何地方,因此您看不到结果。

    您可以在每个 foreach 执行中打开所需的 csv 文件并附加新字符串,但我想提出一个不同的解决方案。

    如果可以,请尝试始终使用 Spark 的内置功能,因为它(通常)在处理空输入方面更加优化和更好。您可以通过以下方式达到同样的目的:

    import org.apache.spark.sql.functions.{lit, concat, col}
    
    val modifiedFinalResult = finalResult.select(
     concat(
      lit("new values of param1 and param2 are -> "),
      col("input1"),
      lit(","),
      col("input2")
     ).alias("string")
    )
    

    在变量 modifiedFinalResult 中,您将拥有一个带有名为 string 的单列的 spark 数据框,它表示与代码中的变量 string 完全相同的输出。之后,您可以将数据框直接保存为单个 csv 文件(使用重新分区功能):

    modifiedFinalResult.repartition(1).write.format("csv").save("path/to/your/csv/output")
    

    PS:也是对未来的一个建议,尽量避免以数据类型命名变量。

    更新:通过使用“concat_ws”而不是 concat 和合并到每个字段来修复空行问题。似乎一些为空的值在转换后将整个连接字符串转换为空。尽管如此,这个解决方案现在仍然有效!

    【讨论】:

    • 如果可行,我会检查并更新!但是我想补充一点,字符串捕获不是我将在 foreach 中执行的唯一操作,还有另一个函数“TopicWriter.save(string, topic2)”,它实际上产生了一个 kafka 主题。有什么建议如何将这些组合在一起吗?因为我看到你建议从旧的数据框创建一个新的数据框并编写... PS:我对“字符串”变量名的不好,我只准备了这个与我的代码非常相似... :)
    • 知道了,对不起,我假设您的代码中的注释行您希望将其保存为 csv 文件。是的,那么确实使用 foreach 是要走的路,但我仍然会在 modifiedFinalResult 数据帧上应用 foreach,因为该操作将更加优化且执行起来更安全:modifiedFinalResult.foreach{row => TopicWriter.save(row.getAs[String]("string"), topic2)}
    • 可以做到。我将测试并看看它是如何执行的。此外,由于这些是微批处理,需要在 1 分钟内完成,创建另一个 df 可能会增加开销......我会在这里更新。感谢帮助:)
    • 我测试了该方法,它在 spark-shell 中按预期工作。但是,面临两个问题: 1. 使用 modifiedFinalResult 时,来自 spark 作业主题和 hdfs 文件的值为“null”。 spark-shell 在使用 modifiedFinalResult.show(1,false) 时给了我正确的输出 2. hdfs 位置为每个微批处理创建空的 0 字节文件。如何避免创建空文件或追加到同一个文件?
    • 你能分享你用来将行推入主题的代码吗?因为我无法直接看到为什么会发生这种情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多