【问题标题】:spark read partitioned data in S3 partly in glacierspark部分在冰川中读取S3中的分区数据
【发布时间】:2018-01-29 14:03:05
【问题描述】:

我在 S3 的 parquet 中有一个数据集,按日期 (dt) 分区,最早的日期存储在 AWS Glacier 中以节省一些钱。例如,我们有...

s3://my-bucket/my-dataset/dt=2017-07-01/    [in glacier]
...
s3://my-bucket/my-dataset/dt=2017-07-09/    [in glacier]
s3://my-bucket/my-dataset/dt=2017-07-10/    [not in glacier]
...
s3://my-bucket/my-dataset/dt=2017-07-24/    [not in glacier]

我想读取这个数据集,但只是尚未在冰川中的日期子集,例如:

val from = "2017-07-15"
val to = "2017-08-24"
val path = "s3://my-bucket/my-dataset/"
val X = spark.read.parquet(path).where(col("dt").between(from, to))

不幸的是,我有例外

java.io.IOException: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: The operation is not valid for the object's storage class (Service: Amazon S3; Status Code: 403; Error Code: InvalidObjectState; Request ID: C444D508B6042138)

当某些分区位于 Glacier 中时,我似乎火花不喜欢分区数据集。我总是可以专门阅读每个日期,在最后添加带有当前日期和reduce(_ union _) 的列,但这很丑陋,应该没有必要。

是否有任何提示可以读取数据存储区中的可用数据,即使冰川中有旧数据?

【问题讨论】:

  • 我不相信这是可能的。 AWS Glacier 似乎不支持下推谓词...
  • 如果您需要检索一些最近的数据,请不要使用冰川。这不值得麻烦,您可能会陷入定价陷阱。只需存储您的数据和标准 IA。 medium.com/@karppinen/…
  • 嗨,没有实际意义。我不想解冻 Glacier 中的数据(这会非常昂贵)。我的观点是我想使用我的数据集的分区,这些分区还没有在冰川中,但其他分区(我不想阅读)是!我认为唯一的方法是修改 AWS SDK,使其根本不尝试扫描冻结的分区。
  • @Boris:你能找到答案吗?鉴于现在有更多的冰川可供选择(深层冰川),这个过程变得很痛苦。有什么建议? PS:我确实在jira.apache.org/jira/browse/SPARK-21797看到了这里的讨论
  • 不,还没有修复。如果您实现了issues.apache.org/jira/browse/HADOOP-14837,那么spark 可以看到哪个离线,并且可能跳过它,但实际上,这是Spark 不必担心的问题。拆分离线和热数据或期望堆栈跟踪

标签: apache-spark amazon-s3 partitioning amazon-glacier


【解决方案1】:

你得到的错误与 Apache spark 无关,因为 Glacier 服务在 Glacier 存储类中的短 S3 对象不能以与普通对象相同的方式访问,它们需要在它们之前从 Glacier 检索可以阅读。

Apache Spark 无法直接处理映射到 S3 的冰川存储 TABLE/PARTITION。

java.io.IOException: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: 该操作对对象的存储类无效(服务: 亚马逊 S3;状态码:403;错误代码:无效对象状态;要求 编号:C444D508B6042138)

当 S3 从 S3 存储类中移动任何对象时

  • 标准,

  • STANDARD_IA,

  • REDUCED_REDUNDANCY

    对于 GLACIER 存储类,您有对象 S3 已存储在 Glacier 中,这是不可见的 给您,S3 将只计费 Glacier 存储费率。

它仍然是一个 S3 对象,但具有 GLACIER 存储类。

当您需要访问其中一个对象时,您可以启动还原, 哪个临时复制到 S3 中。

将数据移入 S3 存储桶并读入 Apache Spark 将解决您的问题。

注意:Apache Spark、AWS athena 等无法直接从 glacier 读取对象,如果您尝试将得到 403 错误。

如果您使用 Glacier 存储选项归档对象,则必须 在尝试检索之前检查对象的存储类 它。如果对象是,惯用的 GET 请求将按预期工作 存储在 S3 标准或减少冗余 (RRS) 存储中。它会 如果对象存档在 Glacier 中,则失败(出现 403 错误)。在这 在这种情况下,您必须使用 RESTORE 操作(如下所述)来使 您的数据在 S3 中可用。

【讨论】:

    【解决方案2】:

    403 错误是由于您无法读取 Glacier 中存档的对象,source

    从 Glacier 读取文件

    如果你想从 Glacier 读取文件,你需要在 Apache Spark 中使用它们之前将它们恢复到 s3,在恢复命令中提到的时间,s3 上会提供一个副本,详细信息see here,你可以使用S3 控制台、cli 或任何可以执行此操作的语言

    丢弃一些您不想恢复的 Glacier 文件

    假设您不想从 Glacier 恢复所有文件并在处理过程中丢弃它们,从 Spark 2.1.12.2.0 您可以忽略这些文件(使用 IO/Runtime Exception),方法是将 spark.sql.files.ignoreCorruptFiles 设置为 @ 987654328@source

    【讨论】:

      【解决方案3】:

      如果您通过 Hive 定义表,并使用 Hive 元存储目录对其进行查询,则它不会尝试进入未选择的分区。 看看 spark.sql.hive.metastorePartitionPruning 设置

      【讨论】:

        【解决方案4】:

        试试这个设置: ss.sql("设置 spark.sql.hive.caseSensitiveInferenceMode=NEVER_INFER") 要么 添加 spark-defaults.conf 配置:

        spark.sql.hive.caseSensitiveInferenceMode NEVER_INFER
        

        【讨论】:

          【解决方案5】:

          来自 Amazon (s3://) 和 ASF (s3a://) 的 S3 连接器不适用于 Glacier。当然,没有人针对冰川测试 s3a。如果有问题,您将不得不自己解决。只需将数据复制到 s3 或本地 HDFS 上,然后在那里使用它

          【讨论】:

            猜你喜欢
            • 2020-04-27
            • 1970-01-01
            • 1970-01-01
            • 2017-04-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-12-15
            • 1970-01-01
            相关资源
            最近更新 更多