Spark:将数据写入正在读取的位置而不会丢失数据

Spark: writing data to place that is being read from without loosing data

请帮助我了解如何使用 EMR 和 S3 将数据毫无问题地写入也正在读取的位置。 所以我需要读取分区数据,找到旧数据,删除它,写回新数据,我在这里考虑两种方法:

  1. 读取所有数据,应用过滤器,使用保存选项写回数据 SaveMode.Overwrite。我在这里看到一个主要问题 - 在写入之前它会删除 S3 中的文件,因此如果 EMR 集群在删除之后但在写入之前由于某种原因出现故障 - 所有数据都将丢失。我可以使用动态分区,但这意味着在这种情况下我会丢失 1 个分区的数据。
  2. 与上面相同,但写入临时目录,然后删除原始目录,将所有内容从临时目录移动到原始目录。但由于这是 S3 存储,它没有移动操作,所有文件都将被复制,这可能有点贵(我将使用 200GB 的数据)。

有没有其他方法或者我对 spark 的工作方式有误?

你没有看错。从 EMR/Hadoop 上的 table 中删除记录的过程在您描述的方式和更多方面都很痛苦。失败的作业、小文件、分区交换、元数据操作缓慢...

有多种格式和文件协议可以在 table 存储的 S3 之上添加事务处理能力。开放的 Delta Lake (https://delta.io/) 格式,支持事务性删除、更新,merge/upsert 并且做得很好。您可以像您描述的那样阅读和删除(比如出于 GDPR 目的)。您将有一个事务日志来跟踪您所做的事情。

关于第 2 点,只要您的文件数量合理,您的费用应该适中,数据费用约为 23 美元/TB/mo。但是,如果您以太多小文件结束,那么列出文件和获取文件的 API 成本会很快加起来。 Managed Delta(来自 Databricks)将通过压缩、数据缓存、数据跳过、z-ordering

帮助加快 table 上的许多操作

免责声明,我为 Databricks 工作....