【问题标题】:NDB query periodically not finding entityNDB 查询定期找不到实体
【发布时间】:2012-12-12 19:53:30
【问题描述】:

我有一个帐户密钥,我在处理项目时会检查它。此密钥可防止我花时间处理不再有效的项目。在处理的内部循环中,我验证我仍然可以找到我正在处理的密钥。

实体定义:

class AuthorizedKey(ndb.Model):
    secret_key = ndb.StringProperty()
    ...additional fields...

我用来检查的代码:

authorized_key = AuthorizedKey.query(AuthorizedKey.secret_key == first_key).get()

first_key 是一个字符串,它与已验证且位于数据存储区中的 AuthorizedKey 实体匹配。根据密钥,它在几周或几个月内没有被修改过。

此查询定期无法检索结果。大约万分之一。错误似乎分布在键之间(即问题不在于一条记录)。

关于如何摆脱这些错误的任何建议?我需要存储在 AuthorizedKey 中的信息才能准确处理请求。如果传入的数据没有密钥,我想尽快停止处理。

更新 --- 与查询匹配的记录通常在使用前几天创建。这些记录平均存在几个月。他们已经工作了数百万次,以前存在过,并且继续存在。有时,对 get() 调用的响应是 None。

虽然多条记录都出现了这个问题,但一条特定记录在创建后大约 2 天就一直被访问。几天前我刚刚在内部循环上添加了监控代码。没有返回错误信息。

"if not authorized_key:" 

在上面的代码大约每 10,000 次返回 False 之后。在工作之前和之后访问。一个具有与我的论点相匹配的 secret_key 的实体已经存在了将近 8 个月,并且已成功访问了数百万次。这就是我提出问题的原因,寻求帮助。在这种情况下,我悄悄地失败了,稍后会自动重试。重试工作正常。完全相同的数据。

除了这个问题的奇怪性质之外,我担心的主要原因是:

  • 核心系统的可靠性
  • 系统的其他区域可能不会像这个区域那样优雅地退化。

【问题讨论】:

  • 您确定特定的AuthorizedKey 实体在数据存储区中并且没有被您的应用程序的任何其他进程删除?当您在失败后立即查询该键时,您是否获得实体?
  • 当您谈到existed consistently 时,您是说密钥/实体仍然存在吗?您是否尝试在未找到“错误”后检索实体?
  • 实际错误是什么?数据存储错误有很多种。
  • @bossylobster 没有'错误',错误是找不到实体。
  • 您是否 100% 确定 first_key 在数据存储中完全匹配?是否可能 first_key 有时会在末尾有空格或特殊字符或不同的编码?

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


【解决方案1】:

您使用的是非祖先查询,因此您可能会得到最终一致的结果。如果实体是相当新的,则对其进行查询可能无法显示它。

【讨论】:

  • 在新创建的实体被复制到云端之前,最终一致性是否只是一个问题?
  • 好的,我看错了你的答案。他在谈论一个更老的实体。
  • 我刚刚看到有关这些实体变旧的更新。听上去其实挺吓人的。我想知道这是否可能是 ndb 错误,因为可以缓存 ndb get 请求......我想知道 ndb 缓存中是否存在一个很少失败的小计时错误。
  • NDB 不缓存查询。
  • @TheJacobTaylor 正在检查异常?即你确定它没有返回任何结果,而不是失败并出现一些异常,表明数据存储有问题?
【解决方案2】:

原来这个内部处理代码是以两种方式调用的。第一种模式拉出一批并处理它们。如果批次中的项目太多,它会安排后续任务以供以后使用。安排后续任务时,它位于默认命名空间以外的命名空间中。

第二种模式是作为后续任务,它会继承它所在的命名空间。这意味着我现在在错误的命名空间中寻找 AuthorizedKey 而没有找到它。我的批量相当大,但不是天文数字。当一个设备非常活跃或系统负载过重时,事件可能会达到该标记,从而非常偶尔地导致错误。

感谢大家的建议和调试帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 2014-10-26
    • 2011-06-18
    相关资源
    最近更新 更多