【问题标题】:Asynchronous GAE Datastore Queries Not Firing Correctly异步 GAE 数据存储查询未正确触发
【发布时间】:2014-10-29 14:28:23
【问题描述】:

我在执行异步 GAE NDB 数据存储查询时遇到问题。出于测试目的,假设我执行

l = []
for i in range (0,50):
    qry = NDBNetLoc.query(NDBNetLoc.netloc == 'imdb.com').get()
    l.append(qry)

netloc 是我模型的索引属性(没有其他属性;我在此处修复字符串,但通常查询的字符串是唯一的)。这当然会在请求中产生“瀑布”:

http://imgur.com/a/uckrh#FAON8pZ

这是应该异步的规范请求类型(根据 Google)。所以相反,我执行

futs = []
for i in range (0,50):
    qry = NDBNetLoc.query(NDBNetLoc.netloc == 'imdb.com').get_async()
    futs.append(qry)

for fut in futs:
    l.append(fut.get_result())

但我没有看到任何改进。虽然每个请求一个接一个地触发,但每个调用需要更长的时间(持续时间随着i 的增加而减少)

http://imgur.com/a/uckrh#eUVfLrG

此外,请求似乎直到第二个 for 循环才会触发。如果我在这个循环前面添加一个time.sleep(2),我会得到类似

http://imgur.com/a/uckrh#SztJnkn

这让我很困惑,因为我认为请求会在 Future 对象创建后立即触发。所以我的两个问题是 1)为什么在实例化每个未来对象时请求没有触发,以及 2)为什么现在每个请求都需要更长的时间(到异步或同步执行此操作的时间等同于完成)?

编辑: 我应该补充一点,我没有对唯一 netlocs 列表进行简单的 IN 查询的原因是因为我最终会运行更复杂的查询(即获取所有具有 propertyA = foo 和一个特定祖先的 Model2 NDBNetLoc 从第一个查询返回,对于许多 NDBNetLocs 和许多 foo)。

【问题讨论】:

  • 可能适用于您的情况的建议:如果您说您的字符串是唯一的,您可以将它们用作实体键并执行get_multi这将在一个 RPC 请求中返回所有 50 个结果,而不是 50 个。
  • 这非常适用于我正在做的第一类查询。谢谢谢谢!对于我的一些更复杂的查询(那些查询不是唯一的属性),我仍然必须使用正常的方式。我想我最终会转向 java,但由于时间限制,我将使用 get_multi 并在我的其他查询中吃掉效率低下

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


【解决方案1】:

我在 SO 上找到了这个问题的摘要......我不太熟悉全局解释器锁以及它在此处的应用方式,但我认为解码我的 RPC 的代码是 CPython 字节码,而解释器不是线程安全,所以每次调用都会锁定它。我想我会转向 Java .....

AppEngine Query.fetch_async not very asynchronous?

【讨论】:

    猜你喜欢
    • 2013-02-16
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    相关资源
    最近更新 更多