Spark:将DataFrame写为压缩JSON

时间:2015-08-11 04:08:58

标签: apache-spark compression gzip dataframe apache-spark-sql

Apache Spark的DataFrameReader.json()可以自动处理gzip压缩的JSONlines文件,但似乎并不是让DataFrameWriter.json()编写压缩的JSONlines文件的方法。额外的网络I / O在云中非常昂贵。

有解决这个问题的方法吗?

3 个答案:

答案 0 :(得分:22)

使用Spark 2.X(可能更早,我没有测试)有一种更简单的方法来编写压缩JSON,它不需要更改配置:

val df: DataFrame = ...
df.write.option("compression", "gzip").json("/foo/bar")

这也适用于CSV和Parquet,在设置压缩选项后,只需使用.csv()和.parquet()而不是.json()来编写文件。

可能的编解码器有:none,bzip2,deflate,gzip,lz4和snappy。

答案 1 :(得分:11)

以下解决方案使用pyspark,但我假设Scala中的代码类似。

第一个选项是在初始化SparkConf时设置以下内容:

conf = SparkConf()
conf.set("spark.hadoop.mapred.output.compress", "true")
conf.set("spark.hadoop.mapred.output.compression.codec", "org.apache.hadoop.io.compress.GzipCodec")
conf.set("spark.hadoop.mapred.output.compression.type", "BLOCK")

使用gzip自动压缩使用sparkContext生成的任何文件上面的代码。

第二个选项,如果您只想压缩上下文中的选定文件。让我们说“df”是您的目标数据框和文件名:

df_rdd = self.df.toJSON() 
df_rdd.saveAsTextFile(filename,compressionCodecClass="org.apache.hadoop.io.compress.GzipCodec")

答案 2 :(得分:5)

SparkConf上设置压缩选项不是是一种很好的做法,是可以接受的答案。它全局更改了行为 ,而不是按文件指示设置。事实是,显式总是比隐式更好。在某些情况下,用户无法轻松操纵上下文配置,例如spark-shell或设计为另一个子模块的代码。

正确的方法

自Spark 1.4起,支持使用压缩方式编写DataFrame。实现该目标的几种方法:

一个

df.write.json("filename.json", compression="gzip")

就是这样!只需使用DataFrameWriter.json()

魔术隐藏在代码pyspark/sql/readwriter.py

@since(1.4)
def json(self, path, mode=None, compression=None, dateFormat=None, timestampFormat=None):
    """Saves the content of the :class:`DataFrame` in JSON format
    (`JSON Lines text format or newline-delimited JSON <http://jsonlines.org/>`_) at the
    specified path.

    :param path: the path in any Hadoop supported file system
    :param mode: ...

    :param compression: compression codec to use when saving to file. This can be one of the
                        known case-insensitive shorten names (none, bzip2, gzip, lz4,
                        snappy and deflate).
    :param dateFormat: ...
    :param timestampFormat: ...

    >>> df.write.json(os.path.join(tempfile.mkdtemp(), 'data'))
    """
    self.mode(mode)
    self._set_opts(
        compression=compression, dateFormat=dateFormat, timestampFormat=timestampFormat)
    self._jwrite.json(path)

受支持的压缩格式为bzip2,gzip,lz4,snappy和deflate,不区分大小写。

scala API应该相同。

另一个

df.write.options(compression="gzip").json("filename.json")

与上述类似。可以提供更多选项作为关键字参数。自Spark 1.4起可用。

第三

df.write.option("compression", "gzip").json("filename.json")
从Spark 1.5开始添加了

DataFrameWriter.option()。一次只能添加一个参数。