【问题标题】:saving compressed json from spark从 spark 中保存压缩的 json
【发布时间】:2019-02-19 18:08:13
【问题描述】:

从 Spark RDD,我想将 JSON 数据暂存并存档到 AWS S3。压缩它才有意义,而且我有一个使用 hadoop 的GzipCodec 工作的进程,但有些事情让我对此感到紧张。

当我在这里查看org.apache.spark.rdd.RDD.saveAsTextFile 的类型签名时:

https://spark.apache.org/docs/2.3.0/api/scala/index.html#org.apache.spark.rdd.RDD

类型签名是:

def saveAsTextFile(path: String, codec: Class[_ <: CompressionCodec]): Unit

但是当我在这里检查可用的压缩编解码器时:

https://spark.apache.org/docs/2.3.0/api/scala/index.html#org.apache.spark.io.CompressionCodec

父特征CompressionCodec 和子类型都说:

编解码器的有线协议不能保证跨版本的 Spark 兼容。这旨在用作单个 Spark 应用程序中的内部压缩实用程序

这不好......但没关系,因为 gzip 可能更容易跨生态系统处理。

类型签名说编解码器必须是CompressionCodec的子类型...但我尝试以下保存为.gz,它工作正常,即使hadoop的GzipCodec不是&lt;: CompressionCodec

import org.apache.hadoop.io.compress.GzipCodec
rdd.saveAsTextFile(bucketName, classOf[GzipCodec])

我的问题:

  • 这可行,但有什么理由不这样做……还是有更好的方法?
  • 与内置压缩编解码器不同,这会在 Spark 版本(和其他版本)中保持稳健吗?

【问题讨论】:

    标签: json scala apache-spark hadoop gzip


    【解决方案1】:

    那么,对于初学者来说,您是绑定到 RDD 还是可以使用 DataSets/DataFrames ?

    使用 DataFrames 你可以使用类似的东西

     df.write.format("json").
        option("compression", "org.apache.hadoop.io.compress.GzipCodec").
        save("...")
    

    但是,有一些注意事项。压缩很棒,但如果你的文件 生成非常大,你要记住 gzip 不是可拆分的格式,也就是说, 如果您想稍后处理该文件,则必须由一名工作人员读取。 例如,如果您的文件是不可拆分的并且为 1G,则需要 T 时间来处理,如果它是可拆分的(如 LZO、Snappy 或 BZip2),则可以在 T/N 中处理它,其中 N 是拆分的数量(假设 128MB 块,大约是 8 个)。 这就是 Hadoop 使用 SequenceFiles(可拆分,并在一个块内使用 gzip)的原因,这也是为什么存储到 S3 时选择的压缩格式通常是 Parquet 的原因。 Parquet 文件比 Gzipped 文件小,并且是可拆分的,也就是说,它的内容可以由多个 worker 处理。 您仍然可以使用 gzip 压缩的文本文件,但将它们保持在 ~100/200Mbyte 范围内。

    归根结底,这实际上取决于您打算如何处理 S3 中的数据。

    会被查询吗?在这种情况下,Parquet 是一种更好的格式选择。

    它会被读取/复制到其他不理解 parquet 的系统吗?然后gzip压缩就OK了。而且它很稳定,您不必担心它会发生变化。 你可以自己试一试,在 S3 上保存一些示例数据,你仍然可以用任何 gzip 工具打开它。

    【讨论】:

    • 好消息!谢谢! Parquet 在某些地方是有意义的,但我必须接触 4 个 AWS 环境,而且我在使用 s3a api 和 parquet 时遇到了麻烦。对于 json/.gz,键是环境变量,我使用 sc.hadoopConfiguration.set() 即时设置,但对于镶木地板则失败。我的解决方法是在 core-site.xml 中硬编码为fs.s3[n].awsAccessKeyId/awsSecretAccesKey,然后将 s3 和 s3n 用于镶木地板,但这将我限制在我可以访问镶木地板的两个 AWS 环境中(s3 和 s3n 各一个)。至少 w/ .gz 我可以随时跨 AWS 环境访问。
    • 奇怪的是它适用于一个但不适用于另一个。你用的是什么版本的hadoop? 2.8 应该允许为不同的桶设置不同的键(hadoop.apache.org/docs/r2.8.0/hadoop-aws/tools/hadoop-aws/…
    • 谢谢!! hadoop 2.7 上的 s3a 和 parquet 有这个问题。[1-3]...现在无法在 hadoop 2.8.4 上重新创建它。此外,在 2.8 中的测试中为每个存储桶设置凭据,因此这开辟了机会,并允许我一次设置所有凭据,而不是即时设置。我真的很感激帮助!这是很酷的东西!
    猜你喜欢
    • 2018-01-09
    • 2015-11-03
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 2017-06-17
    • 2012-10-28
    • 2019-01-19
    • 1970-01-01
    相关资源
    最近更新 更多