5

编辑:见我的答案。问题出在我们的代码中。MR 工作正常,它可能有状态报告问题,但至少输入阅读器工作正常。

我现在进行了几次实验,现在我确信 mapreduce(或 DatastoreInputReader)有奇怪的行为。我怀疑这可能与键范围和拆分它们有关,但这只是我的猜测。

无论如何,这是我们的设置:

  1. 我们有一个名为“AdGroup”的 NDB 模型,在创建此模型的新实体时 - 我们使用从 AdWords 返回的相同 id(它是一个整数),但我们将其用作字符串:AdGroup(id=str(adgroupId))
  2. 我们的数据存储区中有 1,163,871 个这些实体(这是“数据存储区管理员”页面告诉我们的 - 我知道这不是完全准确的数字,但我们不会经常创建/删除广告组,所以我们可以肯定地说,数量为 110 万或更多)。
  3. mapreduce 是这样启动的(从另一个管道):

    yield mapreduce_pipeline.MapreducePipeline(
        job_name='AdGroup-process',
        mapper_spec='process.adgroup_mapper',
        reducer_spec='process.adgroup_reducer',
        input_reader_spec='mapreduce.input_readers.DatastoreInputReader',
        mapper_params={
            'entity_kind': 'model.AdGroup',
            'shard_count': 120,
            'processing_rate': 500,
            'batch_size': 20,
        },
    )
    

因此,我今天尝试多次运行此 mapreduce,而不更改代码中的任何内容,也未更改数据存储区。每次我运行它时,mapper-calls 计数器的值都不同,范围从 450,000 到 550,000。

如果我错了,请纠正我,但考虑到我使用非常基本的 DatastoreInputReader - 映射器调用应该等于实体的数量。所以应该是110万或者更多。

注意:我首先注意到这个问题的原因是因为我们的营销人员开始抱怨“我们添加新的广告组已经 4 天了,它们仍然没有出现在您的应用中!”。

现在,我只能想到一种解决方法 - 将所有广告组的所有键写入 blobstore 文件(每行一个),然后使用 BlobstoreLineInputReader。当然,写入 blob 部分的方式必须不使用 DatastoreInputReader。我现在应该这样做,还是您能提出更好的建议?

注意:我也尝试过使用具有相同代码的 DatastoreKeyInputReader - 结果相似 - 映射器调用在 450,000 到 550,000 之间。

所以,最后提问。如何为实体生成 ID 重要吗?int使用id 代替id更好str吗?一般来说,我能做些什么来让 mapreduce 更容易找到映射它们的所有实体?

PS:我还在尝试这个,以后可能会添加更多细节。

4

1 回答 1

0

经过进一步调查,我们发现错误实际上是在我们的代码中。因此,mapreduce 实际上按预期工作(为每个数据存储实体调用映射器)。

我们的代码调用了一些有时会失败的谷歌服务函数(美妙的神秘 ApplicationError 消息)。由于这些故障,正在重试 MR 任务。但是,我们对任务队列的重试设置了限制。MR 没有以任何方式检测或报告这一点 - MR 在所有分片的状态页面中仍然显示“成功”。这就是为什么我们认为我们的代码一切正常,而输入阅读器有问题。

于 2013-03-26T08:00:44.407 回答