GAE Map Reduce - 不止一次击中实体?

时间:2012-03-30 15:06:04

标签: google-app-engine mapreduce

我正在使用Map Reduce(http://code.google.com/p/appengine-mapreduce/)对一组实体执行操作。但是,我发现我的操作正在重复。

地图缩小地图有时会针对特定实体多次调用吗?即使他们在最初的时间没有失败,情况会是这样吗?

修改:这里有更多详情。

def reparent_request(entity):
    #check if the entity has a parent    
    if not is_valid_to_reparent(entity):
        return

    #copy it
    try:
        copy = clone_entity(Request, entity, parent=entity.user)
        copy.put() #we hard put here so we can use the reference later in this function.
    except:
        ...

    ... update some references to the copied object ...

    #delete the original       
    yield op.db.Delete(entity)

最后,我确定地留下了两个实体,都是新的父母。

2 个答案:

答案 0 :(得分:0)

之前我已经重新设计了一大堆实体 - 由于你所面临的确切问题,这是一场噩梦。

我要做的是:

  1. 创建新队列。确保其已暂停,并且您有大量专用于队列的存储空间。这只是暂时的,但你需要它。
  2. 不是在地图缩减作业中编辑实体,而是将它们添加到队列中,其名称对于每个实体都是唯一的。关键工作正常。
  3. 当添加到队列时,因为它已暂停,如果您尝试将相同的命名队列添加两次,则会收到错误 - 因此请抓住错误并跳过它,因为您知道该实体必须已被地图触摸减少工作。
  4. 如果您确信每个实体都有匹配的队列任务且地图缩减作业已完成,请取消暂停您的队列。队列将进行重新整理。
  5. 几点说明: *任务队列大小可以变得很大。不记得数字,但这是演出。此外,队列的大小不会实时更新 - 所以当队列几乎为空时,不要担心它可能仍然会说任务。 *我相信队列存储的可靠性是未知的。它没有发生在我们身上,但队列物品可能会消失。幸运的是,您可以多次重新运行此过程以确保其正常工作,尤其是在您删除实体时。 *您可能希望确保队列具有并发限制。没有一个,执行一些任务的延迟绝对会削弱您的应用程序。学到了很难的方法!我认为30个并发任务对我们来说非常好。

    希望这很有用,如果你想出任何改进,请告诉我!

答案 1 :(得分:0)

App Engine mapreduce在任务队列上运行,就像使用任务队列的任何其他东西一样,任务必须是幂等的 - 也就是说,多次运行它们应该与运行它们一次具有相同的效果。任务有时会不止一次; mapreduce库也可能有自己重新运行映射器任务的原因。

在您的情况下,我建议使用其ID与旧实体相同的密钥创建新实体;这样多次运行它只会覆盖同一个实体。