编辑:见我的答案。问题出在我们的代码中。MR 工作正常,它可能有状态报告问题,但至少输入阅读器工作正常。
我现在进行了几次实验,现在我确信 mapreduce(或 DatastoreInputReader)有奇怪的行为。我怀疑这可能与键范围和拆分它们有关,但这只是我的猜测。
无论如何,这是我们的设置:
- 我们有一个名为“AdGroup”的 NDB 模型,在创建此模型的新实体时 - 我们使用从 AdWords 返回的相同 id(它是一个整数),但我们将其用作字符串:
AdGroup(id=str(adgroupId))
- 我们的数据存储区中有 1,163,871 个这些实体(这是“数据存储区管理员”页面告诉我们的 - 我知道这不是完全准确的数字,但我们不会经常创建/删除广告组,所以我们可以肯定地说,数量为 110 万或更多)。
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:我还在尝试这个,以后可能会添加更多细节。