Google Cloud Platform 上的 ndb 查询间歇性地不返回任何内容

Posted

技术标签:

【中文标题】Google Cloud Platform 上的 ndb 查询间歇性地不返回任何内容【英文标题】:ndb query on Google Cloud Platform intermittently returning nothing 【发布时间】:2018-09-08 09:55:14 【问题描述】:

我在 Google Cloud Platform 上部署了一个 Python 应用程序。后台有一个 Google Cloud Datastore,有两种。我使用 NDB 将数据拉入应用程序。

class AttEvent(ndb.Model):
  event = ndb.StringProperty()
  matchdate = ndb.DateTimeProperty()

class MainPage(webapp2.RequestHandler):

  def get(self):

    query = AttEvent.query().order(AttEvent.matchdate)
    for q in query.fetch():
        try:
          # application code

其中一种(上面代码中的 AtEvent)给我带来了麻烦。该应用程序将按预期部署和工作数小时/数天,但随后会间歇性地停止返回数据。调试显示 q 对象是 AttEvent 类型的合法对象,但是对于 values 集合中的每个项目,它都显示“(对象没有字段)”。当应用程序代码尝试引用模型的属性(即 q.event)时,它会失败。

即使我不采取任何行动,查询也会在几分钟/几小时后突然重新开始工作。我看不到任何模式或明显的原因。从用户的角度来看,这显然并不理想。

造成问题的 Kind 是静态数据,实际上只包含 3 个实体。另一种是事务性的,包含数千条记录,但从未表现出相同的行为。

故障的间歇性使我相信这与缓存有关,但我对 Python 和 GCP 还很陌生,所以我不太确定。我试过在查询之前做一个 context.clear_cache() ,但没有效果。

我是否遗漏了一些明显的东西?

【问题讨论】:

这很奇怪。 AttEvent 实体的更改与发生的错误之间是否存在关联?还是在创建或更改任何 AttEvent 实体很久之后才发生错误? 嗨,杰夫。没有相关性。今天又做了一次,但我已经好几天没有对 AttEvent 实体进行任何更新了。 【参考方案1】:

我不知道为什么会这样,但我有一个可能的解决方法。由于数据是静态的并且实体看起来很小,因此您可以将它们存储在实例内存中,而不是每次需要时都查询它们。

将实体存储在模块级变量中,如下所示:

att_entities = AttEvent.query().order(AttEvent.matchdate).fetch()

class AttEvent(ndb.Model):
  event = ndb.StringProperty()
  matchdate = ndb.DateTimeProperty()

class MainPage(webapp2.RequestHandler):

  def get(self):
    for q in att_entities:
        try:
          # application code

只有在启动新实例时才能获得实体,只要它在您第一次完成设置时就可以工作。作为奖励,它会使get 调用更快,因为您不需要从数据存储中检索数据。

您可能需要添加额外的逻辑以根据需要更新att_entities

【讨论】:

谢谢杰夫。我已经发布了更改,现在似乎可以正常工作。我会让它运行几天,看看它是否成立。假设确实如此,我可能会在页面中添加一个命令行参数,即“forcerefresh=true”,以触发模块级变量的更新。 这将如何解决问题?如果这个实例的查询是错误的,那么它会一直持续到实例被关闭或脚本刷新。一定有其他事情发生。 @GAEfan,你是对的,它并不能解决根本原因,但由于错误发生的频率很低,只要第一次查询有效,它就会防止错误发生实例的生命周期。此外,即使错误以其他方式修复,这对他来说可能是一个更好的实现。 @GAEfan / Jeff - 我很欣赏这个解决方法,它给了我一些稳定性并确保我的用户不会突然看到空白屏幕。但我同意,我想首先弄清楚为什么会发生这种情况,如果没有别的,以确保不是我在做愚蠢的事情。

以上是关于Google Cloud Platform 上的 ndb 查询间歇性地不返回任何内容的主要内容,如果未能解决你的问题,请参考以下文章

Google Cloud Platform 上的 ndb 查询间歇性地不返回任何内容

如何从我在 Google Cloud Platform 上的部署中删除 Kubernetes 仪表板资源?

为什么无法通过Google Cloud Platform上的Chrome RDP连接到Windows VM?

Google Cloud Platform 和 PCF 上的 Log4j 漏洞 (CVE-2021-44228)

Google Cloud Platform 信用卡验证,擦宝上的虚拟信用卡可以验证吗

Ingress-Nginx-Controller未能找到部署在Google Cloud Platform上的第二项服务