问题: 在将MapReduce库升级到最新版本之后,我们看到了以下问题(我们有一个使用File API的版本,我们在不推荐使用时进行了切换):
运行MapReducer时,在它启动的任务中,来自库的PipelineBase偶尔会变得不可用,从而迫使任务失败。在重试时,它可以正常工作。经过一段随机的时间后,MapReduce库的所述部分变得完全全局不可用。这意味着它在正常的应用程序背景和任务中都不可用。
使应用程序再次响应的唯一方法是重置所有实例并使它们从头开始重新加载整个应用程序代码。
错误:
File "/process/custom_mapper/views.py", line 23, in <module> from process.custom_mapper.pipeline import CustomMapperPipeline
File "/process/custom_mapper/pipeline.py", line 7, in <module> class CustomMapperPipeline(PipelineBase):
TypeError: Error when calling the metaclass bases cannot create 'NoneType’ instances
这意味着PipelineBase是None。查看MapReduce库,在base_handler.py中,从导入PipelineBase的地方,我们可以看到这段代码:
try:
from mapreduce import pipeline_base
except ImportError:
pipeline_base = None
然后:
if pipeline_base:
# For backward compatiblity.
PipelineBase = pipeline_base.PipelineBase
else:
PipelineBase = None
我们的假设是从mapreduce import pipeline_base导入失败。
额外信息: 该应用程序正在使用Flask,MapReducer通过外部端点远程启动。此端点在urls.py中定义,加载映射器控制器类。此类导入CustomMapperPipeline模块。这意味着每次访问URL时,都会实例化CustomMapperPipeline类。如果PipelineBase为None,那么整个应用程序都会失败。
在某个时间点,PipelineBase变得完全不可用。
根据说明,mapreducer包位于app.yaml文件旁边的应用程序的根目录中。
目前只有2件物品被发送到MapReducer。
我们的实施: 地图缩减器遍历项目列表。每个项目将创建一组X编号任务队列来处理数据。每个X任务队列都将自己创建Y个任务队列来处理数据。
我们正在使用以下触发器来缩小地图:
yield MapreducePipeline(
job_name,
'process.custom_mapper.mappers.map_items',
'process.custom_mapper.mappers.reduce_items',
'process.custom_mapper.readers.ItemInputReader',
'mapreduce.output_writers.GoogleCloudStorageOutputWriter',
mapper_params={
[...]
},
reducer_params={
'output_writer': {
'mime_type': 'text/plain',
'bucket_name': bucket_name
}
}
)
CustomInputReader确保将每个项目分发到单个分片。
答案 0 :(得分:0)
有时,它看起来无法加载MapReduce库在处理地图和减少作业时用来管理管道的pipeline
依赖项。管道库作为dependency.txt文件中的依赖项添加,因此驻留在另一个文件夹中,而不是MapReduce库,该库位于应用程序的根目录中。
解决方案是手动复制应用根目录中的pipeline
库。
这是一个很容易解决的问题,但是通过处理base_pipeline导入的方式变得更加困难。我已经打开了一个拉取请求来修复它,我正在等待答案:https://github.com/GoogleCloudPlatform/appengine-mapreduce/pull/82