为啥在 EMR 5.x 版本中取消了对 Amazon S3 的直接写入?
Posted
技术标签:
【中文标题】为啥在 EMR 5.x 版本中取消了对 Amazon S3 的直接写入?【英文标题】:Why are direct writes to Amazon S3 eliminated in EMR 5.x versions?为什么在 EMR 5.x 版本中取消了对 Amazon S3 的直接写入? 【发布时间】:2017-03-21 10:30:34 【问题描述】:阅读本页后:
http://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-hive-differences.html “操作差异和注意事项”->“消除了直接写入 Amazon S3”部分。
我想知道 - 这是否意味着在 EMR 4.x 版本中从 Hive 写入 S3 会比 5.x 版本更快? 如果是这样,这不是一种回归吗? AWS 为什么要取消这种优化? 写入位于 S3 中的 Hive 表是一种非常常见的场景。
有人可以解决这个问题吗?
【问题讨论】:
【参考方案1】:此优化最初由 Qubole 开发并推送到 Apache Hive。 见here。
此功能相当危险,因为它绕过了 Hive 容错机制,并且还迫使开发人员使用通常不必要的中间表,这反过来又会导致性能下降并增加成本。
非常常见的用例是当我们需要将增量数据合并到分区目标表中时,描述为here 查询是从自身插入覆盖表,没有中间表(在单个查询中)它是相当有效的。查询可能要复杂得多,连接了许多表。这是在此用例中启用直接写入时会发生的情况:
分区文件夹在查询完成之前被删除,这导致 Mapper 读取正在写入的同一个表时出现 FileNotFound 异常,因为分区文件夹在映射器执行之前被删除。
如果目标表最初为空,则首次运行成功,因为 Hive 知道没有任何分区并且不读取文件夹。第二次运行失败,因为在映射器完成之前看到 (1) 文件夹已删除。
已知的解决方法会影响性能。以增量方式加载数据通常是用例。在这种情况下,直接写入 S3 功能会迫使开发人员使用临时表来消除 FileNotFoundException 和表损坏。因此,与禁用此功能并从自身写入目标表相比,我们执行此任务的速度要慢得多,成本也要高得多。
第一次失败后,无法成功重启,表不可选择不可写,因为元数据中存在 Hive 分区但文件夹不存在,这导致该表的其他查询中出现 FileNotFoundException,这些查询没有覆盖它。
您所指的亚马逊页面上的描述相同,但细节较少:https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-hive-differences.html
Qubole page 描述了另一个可能的问题,提到了一些使用前缀的现有修复,尽管这不适用于上述用例,因为将新文件写入正在读取的文件夹中无论如何都会产生问题。
此外,映射器、reducer 可能会失败并重新启动,整个会话可能会失败并重新启动,即使推迟删除旧文件也直接写入文件似乎不是一个好主意,因为它会增加不可恢复的失败或数据损坏的机会。
要禁用直接写入,请设置此配置属性:
set hive.allow.move.on.s3=true; --this disables direct write
您可以将此功能用于小任务,并且当不读取正在写入的同一张表时,尽管对于小任务它不会给您太多。当您在一个非常大的表中重写许多分区并且最后移动任务非常慢时,这种优化最有效,那么您可能希望启用它以冒数据损坏的风险。
【讨论】:
以上是关于为啥在 EMR 5.x 版本中取消了对 Amazon S3 的直接写入?的主要内容,如果未能解决你的问题,请参考以下文章
mrjob 在 Amazon EMR 5.x 上不起作用,但在 EMR4.8.3 上运行
当我在 pyspark EMR 5.x 中运行用 Java 编写的 hive UDF 时出错
为啥我们在启用 Kerberos 的 EMR 集群上使用直线连接到 Hive 时使用 Hive 服务主体?