【发布时间】:2015-06-22 08:41:43
【问题描述】:
我们在 AWS EMR 上的 Hadoop 测试环境
- 1 个主节点
- 2个从节点
当我们提交一个小型测试作业时,它会触发 1 个地图任务。一旦map任务完成,就会触发3个reduce任务。
reduce 任务完成后,我们的输出数据将写入 Mongo Collection。但是我们注意到,在某些情况下,输出中有重复的记录。这会导致我们的下游处理任务崩溃,因为它们不期望重复。
我注意到的一件事是,reduce 任务之一有时会被终止,然后由 hadoop 重新启动 - 如果它在向 Mongo 写入数据的过程中被终止,这会导致重复记录吗?
如果 Mongo hadoop 连接器实际上正在向 Mongo 写入数据,有什么方法可以从日志中查看?
有什么方法可以确保在提交给 Mongo 之前完全减少所有数据,以免重复?
如果集群中只有 1 个主节点和 1 个从节点,我们还没有遇到过这个问题。然而,这显然是任何尝试扩展的主要障碍......
更新解决问题
根据 @ruby 的回答,我创建了引导操作来禁用 EMR 上的推测执行。
Mongo 最近还发布了 Mongo hadoop 连接器的更新版本,增加了对推测执行 (1.4.0-rc0) 的支持 https://github.com/mongodb/mongo-hadoop/releases
升级到最新的 jar 文件并添加引导操作后,我发现问题仍然没有完全解决。 经过进一步调查,我发现根本问题与组合器步骤的输出如何路由到减速器任务有关。我们还没有实现自定义分区器,因此 hadoop 使用了我们的 Key 实体的 hashCode() 方法。这是使用 Java Objects.hash() 方法,该方法不应该在分布式系统上使用,因为它不会在不同的 Java 实例之间返回可靠的哈希值。
我们实现了自己的自定义分区器,这最终解决了重复问题。
【问题讨论】: