2012-09-11 42 views
2

因此,最近我一直在阅读大量有关HRD和NDB的文档,但我仍然对NDB如何缓存内容持怀疑态度。使用高复制数据存储+ NDB写入/读取

实施例的情况下:

想象这样一个用户将数据写入和应用需要在写操作之后立即提取它的情况。例如。用户创建“组”(类似于Facebook/Linkedin组),并在创建后立即重定向到组。 (现在,我创建了一批没有分配给它的祖先)

结果:

本地测试时这种功能(具有高启用复制),立即取的新创建的组失败。返回一个NoneType。

问:

已经通过高复制文档和谷歌IO视频了,据我所知,有一个更高的写入延迟,但是,不应该NDB缓存照顾这?即写缓存,然后异步实际写入磁盘,因此,立即读取将从缓存读取,因此应该没有问题。我是否需要执行一些其他设置?

回答

2

很确定您正在运行HRD功能,查询“最终一致”。 NDB的缓存与此行为无关。

2

我怀疑这可能是因为返回了NoneType的重定向。

https://developers.google.com/appengine/docs/python/ndb/cache#incontext

所述的被上下文高速缓存持续仅适用于单个传入的HTTP请求的持续时间和是“可见的”唯一到处理该请求的代码。它很快;这个缓存存在于内存中。当NDB函数写入数据存储时,它也写入上下文高速缓存。当一个NDB函数读取一个实体时,它首先检查上下文缓存。如果在那里找到该实体,则不会发生数据存储交互。 查询不会在任何缓存中查找值。但是,如果高速缓存策略如此说明(但从不到Memcache),则查询结果将写回到上下文高速缓存中。

因此,您正在将值写入缓存,重定向它,然后读取失败,因为重定向上的HTTP请求是不同的,因此缓存不同。

我在这里达到了我的知识极限,但我最初建议您尝试在事务中创建并在完成/成功时重定向。

https://developers.google.com/appengine/docs/python/ndb/transactions

而且当你把模型组到数据存储,你会得到一个钥匙回来。你可以通过该密钥(例如通过urlsafe)重定向,然后你将保证检索数据,因为你有它的明确的关键?毕竟,如果它不在数据存储中,它就不能成为关键。

另外我建议在生产服务器上尝试它,有时行为在本地和生产上可能会有很大的不同。

+0

谢谢。具有上下文缓存的HTTP请求问题很有意义。但是,将其变为事务操作并不能解决问题。纠正我,如果我错了,但Datastore返回一个密钥,然后写入磁盘。这就是为什么即使我得到一个键,当我得到()它,它返回一个NoneType。我猜测一个解决方法可能是memcache它几秒钟...这是一个很好的解决方案吗? –

+0

阅读此:https://developers.google.com/appengine/docs/python/datastore/overview#Datastore_Writes_and_Data_Visibility它也说“因为数据存储获取和祖先查询应用任何未完成的修改之前执行,这些操作始终看到一致的观点所有先前成功的交易,这意味着get操作(通过密钥查找更新的实体)可以保证看到该实体的最新版本。“所以,据我所知,在使用从put生成的密钥获得get后,不应该得到noneType。 –

+0

谢谢。我认为,“一致”的GAE指的是在系统周围没有部分更新的数据。我_think_这并不意味着当密钥返回时写入数据。我做了一些更多的测试,当我更新一个值并且不重定向到一个页面时,我立即看到新值(它来自上下文缓存)。但是,当我更新并重定向时,在第一次加载页面时不会更新该值(由于您提到的HTTP请求问题)。只有当我重新加载时(它有时间写入磁盘)才能看到更新的值。 –