【问题标题】:Avoiding or handling "BadRequestError: The requested query has expired."?避免或处理“BadRequestError:请求的查询已过期。”?
【发布时间】:2016-02-24 05:44:10
【问题描述】:

我正在使用链式延迟任务和查询游标在应用引擎中循环数据。 Python 2.7,使用 db(不是 ndb)。例如

def loop_assets(cursor = None):

  try:

     assets = models.Asset.all().order('-size')

     if cursor:
        assets.with_cursor(cursor)

     for asset in assets.run():

        if asset.is_special():
           asset.yay = True
           asset.put()

  except db.Timeout:
     cursor = assets.cursor()
     deferred.defer(loop_assets, cursor = cursor,  _countdown = 3, _target = version, _retry_options = dont_retry)
     return

这总共运行了大约 75 分钟(每个任务大约 1 分钟),然后引发了这个异常:

BadRequestError: The requested query has expired. Please restart it with the last cursor to read more results.

阅读the docs,唯一声明的原因是:

新的 App Engine 版本可能会更改内部实现细节,使依赖它们的游标失效。如果应用程序尝试使用不再有效的游标,Datastore 会引发 BadRequestError 异常。

所以也许这就是发生的事情,但似乎巧合的是,我第一次尝试这种技术时遇到了“内部实现的变化”(除非它们经常发生)。

对此还有其他解释吗? 有没有办法重新设计我的代码以避免这种情况?

如果没有,我认为唯一的解决方案是标记哪些资产已被处理,然后在查询中添加一个额外的过滤器以排除这些资产,然后在每次进程终止时手动重新启动进程。

作为参考,this question 提出了类似的问题,但接受的答案是“使用光标”,我已经在这样做了,所以这不可能是同一个问题。

【问题讨论】:

  • 值得注意的是,BadRequestError 并不总是导致实现更改的原因——它可能是由单个子查询超时引起的。实施重试可能是一种解决方案。
  • @Adam 谢谢。您是否有指向有关 BadRequestError 其他原因的任何文档的链接? - 很想读一读。

标签: python google-app-engine google-cloud-datastore


【解决方案1】:

你可能想看看AppEngine MapReduce

MapReduce 是一种用于处理大量数据的编程模型 以并行和分布式的方式。它适用于大型, 无法在单个范围内处理的长时间运行的作业 请求,任务如下:

  • 分析应用程序日志
  • 从外部来源汇总相关数据
  • 将数据从一种格式转换为另一种格式
  • 导出数据以供外部分析

【讨论】:

【解决方案2】:

当我问这个问题时,我已经运行过一次代码,并且遇到过一次 BadRequestError。然后我再次运行它,它在没有出现 BadRequestError 的情况下完成,总共运行了大约 6 个小时。所以在这一点上,我会说这个问题的最佳“解决方案”是使代码具有幂等性(以便可以重试),然后添加一些代码进行自动重试。

在我的特定情况下,还可以调整查询,以便在光标“过期”的情况下,查询可以在没有光标的情况下重新启动。有效地将查询更改为:

assets = models.Asset.all().order('-size').filter('size <', last_seen_size)

其中last_seen_size 是从每个任务传递到下一个任务的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 2022-01-05
    • 2014-12-01
    相关资源
    最近更新 更多