【问题标题】:GAE put_multi() entities using backend NDB使用后端 NDB 的 GAE put_multi() 实体
【发布时间】:2013-01-07 23:14:17
【问题描述】:

我正在使用后端使用ndb.put_multi(list_of_entities) 编写多个实体。

我遇到的问题是,在此之后,如果我进行查询,则不会得到任何结果。如果我设置一个睡眠定时器,例如 1 秒,我可以读取我刚刚编写的实体。

例如:

class Picture(ndb.Expando):
    pass

class Favourite(ndb.Expando):
    user_id = ndb.StringProperty(required=True)
    pass

#...make lists with Picture and Favourite kinds
entities = favourites
entities[1:1] = pictures
ndb.put_multi(entities)

favourites = Favourite.query().filter(Favourite.user_id == user_id).fetch(99999, keys_only=True)
logging.info(len(favourites)) #returns 0 in dev_appserver why?

首先假设问题与缓存有关。 但是

阅读NDB Entities Operations on Multiple Keys or Entities

高级说明:这些方法与上下文正确交互,并且 缓存;它们不直接对应于特定的 RPC 调用。

阅读NDB Caching

上下文缓存

上下文缓存仅在单个持续时间内持续存在 传入的 HTTP 请求,并且仅对处理的代码“可见” 那个请求。它很快;这个缓存存在于内存中。当一个新开发银行 函数写入数据存储,它还写入上下文 缓存。当 NDB 函数读取实体时,它会检查上下文 先缓存。如果在那里找到实体,则没有 Datastore 交互 发生。

查询不会在任何缓存中查找值。但是,查询结果是 如果缓存策略这样写,则写回上下文缓存(但是 永远不要使用 Memcache)。

嗯,我在这里迷路了。一切似乎都很好。即使从控制台查询我得到正确的总和,但永远不会在同一个处理程序上,无论什么功能等。

我唯一注意到的是,当等待time.sleep(1) 时,我得到了正确的结果。因此,这与ndb.put_multi 可能无法同步完成有关。好迷茫……

【问题讨论】:

  • 怀疑是这样的:stackoverflow.com/questions/12367904/…最终一致性。
  • 是的,我也怀疑这个@PaulC,但后来我想错了。如果put_multi() 返回是否意味着实体已被放置并且索引和提交成功?我没有使用异步方法。
  • 如果您不使用祖先查询或通过键获取实体,则会遇到最终一致性问题。如果您使用祖先查询或键来获取单个实体,那么它可能是别的东西。
  • Guido 不断提醒我,ndb 缓存仅缓存您通过 key/id 获取的实体。查询不会被缓存。由于您没有使用事务,因此您肯定会遇到最终一致性问题。
  • 你也可以回答并接受你自己的问题 :)

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


【解决方案1】:

早上头脑清醒总比晚上头脑昏沉好。

感谢大家的cmets。问题解决了。您以正确的方式引导我,以便回答我的问题:

我使用祖先查询来正确获取结果。值得一提的是以下内容

Understanding NDB Writes: Commit, Invalidate Cache, and Apply

写入数据的 NDB 函数(例如 put())返回 缓存失效后; 应用阶段异步发生

这意味着在每次放置之后,应用阶段可能还没有完成。

还有:

此行为会影响您查看数据的方式和时间 应用。更改可能不会完全应用于 底层数据存储在 NDB 之后几百毫秒左右 函数返回。更改时执行的非祖先查询 正在应用可能会看到不一致的状态(即,部分但不是全部 改变)。有关写入时间的更多信息和 查询,请参阅 App Engine 中的事务隔离。

还有一些关于读写一致性的事情来自Google Academy Retrieving data from the Datastore

Google App Engine 的 High Replication Datastore (HRD) 提供高 通过同步存储数据为您的读取和写入提供可用性 在多个数据中心。但是,从写入时间的延迟是 承诺,直到它在所有数据中心都可见,这意味着 跨多个实体组的查询(非祖先查询)只能 保证最终一致的结果。因此,结果 此类查询有时可能无法反映最近对 基础数据。 但是,通过键直接获取实体是 始终一致

感谢@Paul C 的不断帮助,感谢@dragonx 和@sologoub 帮助我理解。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    相关资源
    最近更新 更多