Google app engine 如何调试具有数百万次写入的长时间运行的mapreduce作业?
我正在使用库的简单Google app engine 如何调试具有数百万次写入的长时间运行的mapreduce作业?,google-app-engine,mapreduce,Google App Engine,Mapreduce,我正在使用库的简单控件.start\u map()函数来启动mapreduce作业。此作业成功完成,并在生成的/mapreduce/detail?mapreduce\u id=页面上显示约43M个映射器调用。但是,本页没有提到reduce步骤或任何我认为仍在运行的底层appengine管道进程。是否有某种方法返回此调用生成的管道ID,以便我可以查看底层管道以帮助调试此长期运行的作业?我想检索足够的信息来打开此页面:/mapreduce/pipeline/status?root= 下面是我最初用于
控件.start\u map()
函数来启动mapreduce作业。此作业成功完成,并在生成的/mapreduce/detail?mapreduce\u id=
页面上显示约43M个映射器调用。但是,本页没有提到reduce步骤或任何我认为仍在运行的底层appengine管道进程。是否有某种方法返回此调用生成的管道ID,以便我可以查看底层管道以帮助调试此长期运行的作业?我想检索足够的信息来打开此页面:/mapreduce/pipeline/status?root=
下面是我最初用于启动mapreduce作业的代码示例:
from third_party.mapreduce import control
mapreduce_id = control.start_map(
name="Backfill",
handler_spec="mark_tos_accepted",
reader_spec=(
"third_party.mapreduce.input_readers.DatastoreInputReader"),
mapper_parameters={
"input_reader": {
"entity_kind": "ModelX"
},
},
shard_count=64,
queue_name="backfill-mapreduce-queue",
)
以下是映射函数:
# This is where we keep our copy of appengine-mapreduce
from third_party.mapreduce import operation as op
def mark_tos_accepted(modelx):
# Skip users who have already been marked
if (not modelx
or modelx.tos_accepted == myglobals.LAST_MATERIAL_CHANGE_TO_TOS):
return
modelx.tos_accepted = user_models.LAST_MATERIAL_CHANGE_TO_TOS
yield op.db.Put(modelx)
以下是ModelX的相关部分:
class BackupModel(db.Model):
backup_timestamp = db.DateTimeProperty(indexed=True, auto_now=True)
class ModelX(BackupModel):
tos_accepted = db.IntegerProperty(indexed=False, default=0)
为了了解更多的上下文,我正在尝试调试一个我看到的问题,即数据仓库中出现的写操作
2013年3月23日,我们启动了一项MapReduce作业(我们称之为a
),该作业覆盖了一个数据库模型(我们称之为ModelX
),拥有约4300万个实体。7小时后,作业“完成”且/mapreduce/detail
页面显示我们已成功映射所有实体,如下所示
mapper-calls: 43613334 (1747.47/sec avg.)
mapper-calls: 43803632 (964.24/sec avg.)
2013年3月31日,我们在ModelX
上启动了另一个MapReduce作业(我们称之为B)。12小时后,作业完成,状态成功,/mapreduce/detail
页面显示我们已成功映射所有实体,如下所示
mapper-calls: 43613334 (1747.47/sec avg.)
mapper-calls: 43803632 (964.24/sec avg.)
我知道job先生给所有的ModelX
实体写了一封信,因为我们引入了一个新的属性,以前没有一个实体包含这个属性。ModelX
包含如下自动添加属性
backup_timestamp = ndb.DateTimeProperty(indexed=True, auto_now=True)
我们的数据仓库流程在ModelX
上运行查询,以查找在某一天发生更改的实体,然后下载这些实体并将其存储在单独的(AWS)数据库中,以便我们可以对其进行分析。此查询的一个示例是:
db.GqlQuery('select * from ModelX where backup_timestamp >= DATETIME(2013, 4, 10, 0, 0, 0) and backup_timestamp < DATETIME(2013, 4, 11, 0, 0, 0) order by backup_timestamp')
这让我想到,尽管mapreduce作业发出的op.db.Put()调用仍在某些管道或队列中运行,并导致这种涓涓效应
此外,如果我查询具有旧备份\u时间戳的实体,我可以回溯到相当远的地方,仍然可以得到大量实体,但我希望所有这些查询都返回0:
In [4]: ModelX.all().filter('backup_timestamp <', 'DATETIME(2013,2,23,1,1,1)').count()
Out[4]: 1000L
In [5]: ModelX.all().filter('backup_timestamp <', 'DATETIME(2013,1,23,1,1,1)').count()
Out[5]: 1000L
In [6]: ModelX.all().filter('backup_timestamp <', 'DATETIME(2012,1,23,1,1,1)').count()
Out[6]: 1000L
[4]中的:ModelX.all().filter('backup\u timestamp我认为你不会在那里有任何reducer函数,因为你所做的只是启动一个映射器。要完成一个完整的mapreduce,你必须显式地实例化一个,并在它上面调用start
。作为奖励,这回答了你的问题,因为它返回了管道ID,然后你可以在状态URL中使用它。试试看g了解具体问题。您是否希望AWS数据库中有更多的实体?我怀疑问题在于将旧的ModelX实体下载到AWS数据库的过程中,不知何故,它没有捕获所有更新的实体
AWS下载过程是否以任何方式修改了ModelX?如果不是,那么您为什么会对发现带有旧的修改的时间戳的实体感到惊讶?修改的只会在写入操作时更新,而不会在读取操作时更新
有点不相关-关于限制,我通常发现限制的任务队列是问题所在,因此,也许可以检查您的任务在那里有多旧,或者您的应用程序是否由于在其他地方发生大量错误而被限制。control.start\u map不使用管道,并且没有洗牌/减少步骤。当mapreducetus页面显示其已完成,所有与mapreduce相关的taskqueue任务都应已完成。您可以检查队列,甚至暂停队列
我怀疑存在与旧模型的旧索引或最终一致性相关的问题。若要调试MR,请筛选警告/错误日志并按MR id进行搜索。若要帮助处理特定情况,请查看地图处理程序。感谢您的响应,但我不想启动另一个43M写入管道调试这一点。如果这有帮助,我已经为问题添加了一些额外的上下文。我还与GAE企业支持部门联系,希望能够更深入地了解正在发生的事情,我们拭目以待。是的,我希望mapreduce报告写入成功的速率与我的下载脚本检测到它们的速率相同。相反,mapreduce报告4300万次写入成功已完成,但我的下载脚本仅检测到3M。我很惊讶有旧的修改时间戳,因为mapreduce告诉我它已经完成了对每个ModelX
实体的编写。AWS下载程序是只读的。回填mapreduce队列
没有显示异常排队的任务。GAE das中没有任何内容hboards显示我的mapreduce仍在运行,因此出现了这个问题。