编辑:看我的回答。我们的代码存在问题。 MR工作正常,可能有状态报告问题,但至少输入阅读器工作正常。
我现在多次运行实验,现在我确定mapreduce(或DatastoreInputReader)有奇怪的行为。我怀疑这可能与关键范围和分裂它们有关,但这只是我的猜测。
无论如何,这是我们的设置:
AdGroup(id=str(adgroupId))
启动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 - mapper-calls应该等于实体数量。所以它应该是110万或更多。
注意:我之所以首先注意到这个问题的原因是因为我们的营销人员开始抱怨“我们添加了新广告组后的4天,而且他们仍未显示在您的应用中!”。
现在,我只想到一个解决方法 - 将所有广告组的所有密钥写入blobstore文件(每行一个),然后使用BlobstoreLineInputReader。当然,写入blob部分必须以不使用DatastoreInputReader的方式编写。我现在应该继续这样做,还是可以提出更好的建议?
注意:我也尝试使用相同代码的DatastoreKeyInputReader - 结果相似 - mapper-calls介于450,000和550,000之间。
所以,最后问题。如何为实体生成ID很重要?使用int
ID而不是str
ID更好吗?一般来说,我可以做些什么来让mapreduce更容易找到映射它们的所有实体?
PS:我还在试验这个,我可能会在以后添加更多细节。
答案 0 :(得分:0)
经过进一步调查后,我们发现错误实际上在我们的代码中。因此,mapreduce实际上按预期工作(为每个数据存储区实体调用mapper。)
我们的代码调用了一些有时失败的google服务函数(精彩的神秘ApplicationError消息)。由于这些故障,MR任务正在重试。但是,我们已对taskqueue重试设置了限制。 MR没有检测到也没有以任何方式报告 - MR仍在所有分片的状态页面中显示“成功”。这就是为什么我们认为我们的代码一切都很好,并且输入阅读器出了问题。