在Hadoop MapReduce之后将重复记录写入MongoDB(使用Mongo Hadoop Connector)

时间:2015-06-22 08:41:43

标签: mongodb hadoop emr

我们在AWS EMR上的Hadoop测试环境

  • 1个主节点
  • 2个从属节点

当我们提交一个小型测试作业时,它会触发1个地图任务。地图任务完成后,将触发3个减少任务。

当reduce任务完成后,我们的输出数据将被写入Mongo Collection。但是我们注意到在某些情况下,输出中有重复的记录。这导致我们的下游处理任务崩溃,因为它们不期望重复。

我注意到的一件事是,其中一个reduce任务有时被杀死然后由hadoop重新启动 - 如果它在向Mongo写入数据的过程中被杀死,这会导致重复记录吗?

如果Mongo hadoop连接器实际上是在向Mongo写入数据,有没有办法从日志中看到? 有没有办法确保所有数据在提交到Mongo之前完全减少,所以没有重复项?

如果群集中只有1个主节点和1个从节点,我们就没有遇到过这个问题。然而,这显然是任何扩展计划的主要障碍......

使用解决方案更新

基于@ ruby​​的回答,我创建了自举动作以禁用EMR上的推测执行。

Mongo最近还发布了Mongo hadoop连接器的更新版本,增加了对Speculative Execution的支持(1.4.0-rc0) https://github.com/mongodb/mongo-hadoop/releases

升级到最新的jar文件并添加引导操作后,我发现问题仍未完全解决。 经过进一步调查后,我发现潜在的问题与组合器步骤的输出如何被路由到减速器任务有关。我们没有实现自定义分区器,因此hadoop使用了Key实体的hashCode()方法。这是使用Java Objects.hash()方法,该方法不应在分布式系统上使用,因为它不会在不同的Java实例中返回可靠的哈希值。

我们实施了自己的自定义分区程序,最终解决了重复问题。

1 个答案:

答案 0 :(得分:1)

  

通过在驱动程序类或客户端mapred-site.xml中设置这些属性来关闭推测执行。

<property>
      <name>mapred.map.tasks.speculative.execution</name> 
      <value>false</value>
  </property>
   <property>
      <name>mapred.reduce.tasks.speculative.execution</name> 
      <value>false</value>
  </property>