【问题标题】:put_async slow in Google App EngineGoogle App Engine 中的 put_async 速度慢
【发布时间】:2012-03-13 02:48:38
【问题描述】:

我最近在一个带有异步调用的 appengine 应用程序中替换了许多 sycnronous db.put 调用。我不需要在请求的其余部分使用这些数据,所以最初我只是以一种即发即弃的方式调用 put_async 函数。然后我在SO上看到了这篇文章: Appengine: put_async doesn't work (at least in the development server)? ,以及来自应用引擎工程师的回复说您必须在异步对象上调用 wait 或 get_result 以保证它被写入。

所以在我的测试中,所有 put_async 调用都工作正常,但我想确定一下,所以我添加了一个带有变量的全局模块,我可以在所有其他模块中访问该变量,并在每次调用时存储 async ref put_async 在应用程序中。 IE: APP_GLOBALS.async_db_calls.append(db.put_async(whatever_db_model))

然后,我使用 atexit 注册了一个关闭函数,该函数遍历此请求的所有 asycn 调用,并在它们上调用 wait() 以确保它们已写入数据存储区。

工作,但我注意到在此更改后性能极度下降...有没有人对此有任何见解,或者知道更好的方法来使用异步调用进行写入而无需关机功能?

【问题讨论】:

  • 呃,你能详细说明一下为什么需要关机功能吗?您链接到的关于put_async 的问题没有任何关于它的要求...
  • 在响应完成后,为了方便起见,将其用作单个位置以完成所有异步调用(而不是在异步调用之后零碎等待/get_result 调用)
  • 你为什么觉得有必要“敲定”它们?
  • 哎呀..我最初引用了错误的 SO 问题。刚刚修好了。正如您将从问题中看到的那样,Nick 表示有必要保证写入成功。

标签: python google-app-engine datastore


【解决方案1】:

NDB API 的功能可以极大地帮助您解决此问题。但是,在请求完成之前,您总是必须等待 RPC 调用完成,这不是您可以避免的。调用数据存储 API 的 *_async 对应项不会让您在请求之外进行工作。

http://code.google.com/appengine/docs/python/ndb/async.html

【讨论】:

  • 因此,如果我理解正确,基本上除了检查所有 RPC 是否在关闭函数中完成之外,我唯一的选择是:1)在对该上下文有意义的任何地方单独处理每个“期货”对象,或者2) 用@context.toplevel 装饰我所有的处理函数。
  • 经过进一步研究,NDB 不适用于我的大部分数据存储,因为它不支持我广泛使用的许多属性(例如 ReferenceProperty)
  • 你总是想用@context.toplevel 来装饰,这让你可以在不必跟踪你所做的异步调用的情况下处理你的代码,还可以让你创建tasklet以实现进一步的并发性。如果您需要保证您的写入,那么您唯一的选择,AFAIK,是通过每个未来并调用 get_result() 并注意异常。这可能不会比您当前的方法更好(尽管只有测试会告诉您),但至少它由 SDK 提供,并且可能会简化您的代码。尝试编写一小部分代码并检查是否有帮助。
  • 有一个参考属性的变通方法:groups.google.com/group/appengine-ndb-discuss/browse_thread/…,您可以迁移到新的属性名称并在函数上使用 @property 装饰器作为原始属性名称来覆盖这个新语法,而无需更新所有代码。我相信您最了解您的代码,并且迁移到 NDB API 对于已建立和生产中的应用程序而言并非易事!
  • 感谢您的 cmets - 进一步探索了 NDB 文档,将我的数据存储转换为 ndb 将是一个非常大的项目。与此同时,我无法让@context.toplevel 正常工作。使用 python 2.7、webapp2 和装饰调度函数......上下文装饰器是否仅适用于 NDB api?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2015-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-27
相关资源
最近更新 更多