【问题标题】:How to write data as single (normal) csv file in Spark? [duplicate]如何在 Spark 中将数据写入单个(普通)csv 文件? [复制]
【发布时间】:2018-04-13 16:56:24
【问题描述】:

我正在尝试将数据框保存为本地驱动器中的 CSV 文件。但是,当我这样做时,我会生成一个文件夹,并在该分区中写入文件。有什么建议可以克服吗?

我的要求: 获取代码中给出的实际名称的普通 csv 文件。

代码片段: dataframe.coalesce(1).write.mode("overwrite").format("com.databricks.spark.csv").option("header", "true").csv("E:/dataframe.csv")

【问题讨论】:

    标签: scala csv apache-spark spark-csv


    【解决方案1】:

    TL:DR 您正在尝试在分布式环境中强制执行顺序的核心概念。不会有好的结局。

    Spark 不提供这样的实用程序。为了能够以半分布式方式创建一个,您必须实现多步骤、源依赖协议,其中:

    • 你写标题。
    • 您为每个分区编写数据文件。
    • 您合并文件,并指定一个新名称。

    由于它的应用程序有限,仅对小文件有用,并且对于某些源(如对象存储)可能非常昂贵,因此在 Spark 中没有实现这样的功能。

    您当然可以收集数据,使用标准 CSV 解析器(Univoicity、Apache Commons),然后放入您选择的存储中。这是顺序的,需要多次数据传输。

    【讨论】:

      【解决方案2】:

      没有自动的方法可以做到这一点。我看到了两种解决方案

      • 如果本地目录安装在所有执行程序上:像您一样写入文件,然后将 part-*csv 文件移动/重命名为所需的名称
      • 或者,如果该目录并非在所有执行程序上都可用:收集 数据帧到驱动程序,然后使用普通 scala 创建文件

      但是这两种解决方案都会破坏并行性,从而破坏 spark 的目标。

      【讨论】:

        【解决方案3】:

        这是不可能的,但你可以这样做:

        dataframe.coalesce(1).write.mode("overwrite").format("com.databricks.spark.csv").option("header", "true").csv("E:/data/")
        
        import org.apache.hadoop.fs._
        val fs = FileSystem.get(sc.hadoopConfiguration)
        val filePath = "E:/data/"
        val fileName = fs.globStatus(new Path(filePath+"part*"))(0).getPath.getName
        fs.rename(new Path(filePath+fileName), new Path(filePath+"dataframe.csv"))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-03-14
          • 1970-01-01
          • 2022-01-12
          • 2020-02-23
          • 2021-04-16
          • 1970-01-01
          • 2014-04-12
          相关资源
          最近更新 更多