问题标签 [app-engine-ndb]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
450 浏览

google-app-engine - 应用引擎数据存储中的邮政地址模型,公共属性应该如何结构化?

假设我们有基于 2 个模型的数百万个地址。

  1. Address模型具有纯字符串属性,即使对于常见的属性,如county

    /li>
  2. StructuredAddressmodel 通过将每个属性定义为 a 来保留更常见的属性作为对其他模型的引用KeyProperty

    /li>

以下是问题:

  • 当基于常见属性进行查询时,哪种模型更有效zipcode

  • 假设county属性的数量约为 50,而zipcode属性的数量约为数百万。给定数百万个地址记录,在这种情况下哪种模型更有效?

  • KeyProperty在这个例子中使用是否意味着更多的读取操作,并且实际上更高的账单?内置的 ndb 缓存会避免这种情况吗?

0 投票
3 回答
1406 浏览

google-app-engine - 如何使用 NDB 的 id 属性?

对于旧数据存储,我使用了密钥。现在我必须使用 ids(取自NDB Cheat Sheet doc):

但看起来这段代码不起作用 - 记录被添加了几次。

(在我的情况下,user_id 是字符串)

0 投票
4 回答
18059 浏览

google-app-engine - 从数据存储区查询大量 ndb 实体的最佳实践

我在 App Engine 数据存储区遇到了一个有趣的限制。我正在创建一个处理程序来帮助我们分析我们的一个生产服务器上的一些使用数据。要执行分析,我需要查询和汇总从数据存储中提取的 10,000 多个实体。计算并不难,它只是通过使用样本的特定过滤器的项目的直方图。我遇到的问题是,在达到查询截止日期之前,我无法足够快地从数据存储中取回数据以进行任何处理。

我已经尝试了所有我能想到的将查询分块为并行 RPC 调用以提高性能,但根据 appstats,我似乎无法让查询实际并行执行。无论我尝试哪种方法(见下文),RPC 似乎总是会退回到顺序下一个查询的瀑布。

注意:查询和分析代码确实有效,只是运行缓慢,因为我无法从数据存储区快速获取数据。

背景

我没有可以分享的实时版本,但这里是我正在谈论的系统部分的基本模型:

您可以将样本视为用户使用给定名称的功能的时间。(例如:'systemA.feature_x')。标签基于客户详细信息、系统信息和功能。例如:['winxp'、'2.5.1'、'systemA'、'feature_x'、'premium_account'])。因此,这些标签形成了一组非规范化的标记,可用于查找感兴趣的样本。

我正在尝试进行的分析包括获取日期范围并询问每个客户帐户(公司,而不是每个用户)每天(或每小时)使用的一组功能(可能是所有功能)的次数。

所以处理程序的输入类似于:

  • 开始日期
  • 结束日期
  • 标签

输出将是:

查询通用代码

这是所有查询的一些共同代码。处理程序的一般结构是一个使用 webapp2 的简单 get 处理程序,它设置查询参数、运行查询、处理结果、创建要返回的数据。

尝试的方法

我尝试了多种方法来尝试尽快并行地从数据存储中提取数据。到目前为止我尝试过的方法包括:

A. 单次迭代

这更像是与其他方法进行比较的简单基本情况。我只是构建查询并遍历所有项目,让 ndb 做它做的事情来一个接一个地拉它们。

B. 大取数

这里的想法是看看我是否可以进行一次非常大的提取。

C. 跨时间范围的异步获取

这里的想法是认识到样本在时间上的间隔相当好,因此我可以创建一组独立的查询,将整个时间区域分成块,并尝试使用异步并行运行每个查询:

D. 异步映射

我尝试了这种方法,因为文档听起来像是 ndb 在使用 Query.map_async 方法时可能会自动利用一些并行性。

结果

我测试了一个示例查询来收集总体响应时间和 appstats 跟踪。结果是:

A. 单次迭代

真实:15.645s

这个顺序通过一个接一个地获取批次,然后从 memcache 中检索每个会话。

方法 A appstats

B. 大取数

真实:12.12s

实际上与选项 A 相同,但由于某种原因要快一些。

方法 B 应用统计

C. 跨时间范围的异步获取

真实:15.251s

似乎在开始时提供了更多的并行性,但似乎在结果迭代期间因一系列对 next 的调用而减慢了速度。似乎也无法将会话 memcache 查找与挂起的查询重叠。

方法 C 应用程序统计

D. 异步映射

真实:13.752s

这个是我最难理解的。看起来它有很多重叠,但一切似乎都在瀑布中延伸而不是平行。

方法 D appstats

建议

基于这一切,我错过了什么?我只是达到了 App Engine 的限制,还是有更好的方法来并行拉下大量实体?

我不知道接下来要尝试什么。我考虑过重写客户端以并行向应用程序引擎发出多个请求,但这似乎很暴力。我真的希望应用引擎应该能够处理这个用例,所以我猜我缺少一些东西。

更新

最后我发现选项 C 最适合我的情况。我能够优化它以在 6.1 秒内完成。仍然不完美,但要好得多。

在听取了几个人的建议后,我发现以下几点是理解和牢记的关键:

  • 多个查询可以并行运行
  • 一次只能有 10 个 RPC 飞行
  • 尝试去规范化到没有辅助查询的程度
  • 这种类型的任务最好留给映射reduce和任务队列,而不是实时查询

所以我做了什么让它更快:

  • 我从一开始就根据时间对查询空间进行了分区。(注意:分区在返回的实体方面越相等越好)
  • 我进一步对数据进行非规范化以消除对辅助会话查询的需要
  • 我利用 ndb 异步操作和 wait_any() 将查询与处理重叠

我仍然没有得到我期望或喜欢的性能,但它现在是可行的。我只是希望它们是一种更好的方法,可以在处理程序中快速将大量顺序实体拉入内存。

0 投票
1 回答
1343 浏览

app-engine-ndb - 直系父母的祖先查询

我正在尝试使用 App Engine NDB 对递归结构进行建模:

从这里,我想查询 Root 实体的直系子实体。我能做的是查询根的所有后代:

我想做的是:

但似乎ndb api不支持通过(立即)父键进行查询。希望我错了。期待阐明。谢谢

0 投票
2 回答
840 浏览

google-app-engine - NDB 的 GAE Memcache 使用率似乎很低

我有一个带有约 40 GB 数据库的 Google App Engine 项目,但使用 NDB 的读取性能很差。我注意到我的内存缓存大小(在仪表板上列出)只有大约 2 MB。我希望 NDB 隐含地更多地使用 memcache 来提高性能。

有没有办法调试 NDB 的 memcache 使用情况?

0 投票
1 回答
905 浏览

python - 如何创建一个新的模型实体,然后立即阅读它?

我的问题是,创建新模型实体的最佳方法是什么,然后立即阅读。例如,

这通常会引发异常,例如:

即新LeftModel 实体的检索不成功。我在 appengine 中遇到过几次这个问题,而我的解决方案总是有点 hacky。通常我只是把所有东西都放在一个 try except 或一个 while 循环中,直到成功检索到实体。如何确保始终检索模型实体而不冒无限循环的风险(在 while 循环的情况下)或弄乱我的代码(在 try except 语句的情况下)?

0 投票
2 回答
1764 浏览

google-app-engine - 在 NDB 中按计数查询重复的属性

是否有一种有效的机制来查询 NDB 中重复属性中的项目数?

我想做类似的事情:

但这当然行不通。

0 投票
1 回答
2266 浏览

python - 最好通过 keys_only=True 然后 get_multi 查询还是完全查询?

我将 NDB 与 python 2.7 一起使用,并打开了线程安全模式。

我知道使用 NDB 查询实体不使用本地缓存或内存缓存,而是直接进入数据存储区,这与通过键名获取不同。(如果这个前提不正确,剩下的问题可能是多余的。)

因此,一个好的范例是仅使用 keys_only=True 进行查询,然后执行 get_multi 以获得完整的实体?

好处是 keys_only=True 查询比 keys_only=False 快得多,get_multi 可能只是命中 memcache 并且通过调用 get_multi 您的实体现在保存在 memcache 中,以防您需要再次进行查询。

缺点是您现在有一个 RPC 查询调用 + get_multi 调用,我认为您可以在一个 get_multi 中调用的实体数量是有限的,因此您的有效查询大小可能会受到限制。

你怎么看?我们是否应该只使用 keys_only=True 查询然后执行 get_multi?是否存在某些最小和最大查询大小限制,使该技术不如仅执行返回完整实体的查询有效?

0 投票
1 回答
3548 浏览

python - 按 KeyProperty 的 NDB 查询过滤器

我在 ndb 模型中有一个类方法,我在其中按“用户”(没问题)和“行业”进行过滤。

问题是实体Recommendation没有行业属性,但具有Stock属性,即 Stock 的 KeyProperty,而Stock具有行业属性

如何修复get_last_n_recommendations_for_user_and_industry方法以按行业过滤,即股票的 KeyProperty?

当我这样做时,我有这个错误:

0 投票
1 回答
225 浏览

python - 在命名空间、多租户 Appengine 应用程序中管理全局数据

我正在使用命名空间设计一个多租户系统。

用户通过 OpenID 进行身份验证,用户模型保存在 Cloud Datastore 中。用户将被分组到组织中,也在数据库中建模。应用程序数据需要按组织进行分区。

所以想法是将命名空间映射到“组织”。

当用户登录时,会在会话中查找并保存他们的组织。

WSGI 中间件检查会话并相应地设置命名空间。

我的问题涉及如何最好地管理“全局”数据(即用户和组织)和应用程序数据(按组织命名空间)之间的切换

我目前的方法是使用 python 装饰器和上下文管理器来临时切换到全局命名空间,以进行访问此类全局数据的操作。例如

或者

这也意味着模型具有跨命名空间的 KeyProperties:

这似乎是一种合理的方法吗?我觉得这有点脆弱,但我怀疑这是因为我不熟悉在 App Engine 中使用命名空间。我的替代想法是将 Cloud Datastore 中的所有“全局”数据提取到外部 Web 服务中,但如果可能的话,我宁愿避免这种情况。

非常感谢您的建议。提前致谢