2013-04-21 95 views
3

如何现有持久性框架为GAE,像物化DataNucleus将嫩枝等处理数据存储的“最终一致”的本质?技术在处理数据存储的最终一致性

我正在使用DatastoreService图层中的数据存储(我现在没有使用这种持久性框架)。

在我的单元测试过程中,我有时会得到正确的对象数,有时候不会。这是预期的。

这是我的JUnit帮手配置:

private final LocalServiceTestHelper helper = 
    new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig() 
     .setDefaultHighRepJobPolicyUnappliedJobPercentage(50)); 

现在,即使我已经放在PUT/GET在do-while循环与重试的方法(与4重试次数),它仍然偏出放/取实体。

那么现在,对于那些指定的框架,他们是否能够保证,如果我把3个对象,我会得到3个对象?如果是的话,它是如何实施的?

我能想到的唯一的事情就是使用Memcache,也就是说,我的方法将首先尝试从它获取实体,并且如果它错过了这是检查数据存储的唯一时间。这是一种合理的方法,还是有更好的方法或正确的方法?

+0

对于Memcache而言,每一次投入和获得成本会高吗?在内存和CPU方面? – 2013-04-21 06:16:10

+0

您建议的缓存方法如何处理群集应用程序? (多个实例读取和写入相同的记录) – radai 2013-04-21 07:34:52

回答

2

如果您希望您的查询的强一致性则有两种选择:

  1. )使用 ancestor 查询。

  2. )使用datastore get 操作,而不是查询,他们有很强的一致性。

如果你仔细地构建你的密钥名称,通常可以使用gets而不是查询。您的其他选择,如果您需要对给定用户“出现”一致的查询,则应用一些小技巧:将用户更改注入结果中。所以,如果他们改变他们的名字,并且你重定向到他们的个人资料页面,那么在发送他们之前将他们的改变注入结果。

+0

好点,我记得那些基于查询的人很难,即使我使用PreparedQuery的count方法失败。 – xybrek 2013-04-21 17:37:52

+0

是的,你必须使用祖先查询,如果你想这是准确的。请记住,在某些情况下,使用祖先查询将使用额外的索引,这意味着写入费用会稍微高一些 - 无论是在金钱和时间方面。 – 2013-04-24 03:38:04

2

Objectify does 不是以任何方式,形状或形式处理最终一致性。开发人员在使用Objectify或任何其他库时必须牢记这一点。

围绕查询执行一个do/while循环,或者添加一个wait()并不能保证强一致性。充其量,你会增加获得最新结果的可能性,但这远没有确定。

Memcache在这里也没有提供任何保证,因为它是不可靠的存储。 memcache put()函数是NO-OP是完全合法的,即什么都不做。

要解决您的核心问题,您需要以强一致性的方式设计您的应用程序。因此,您可以使用强大的一致性数据存储区读取操作(如获取或祖先查询)。或者你可以通过HTTP传递一些数据。

+0

强一致性? – xybrek 2013-04-21 08:04:34

+0

所以在我的单元测试中,我将不得不做一个你认为会做的wait()方法?我的意思是,我希望它不会失败,即使一次,使用下面的设置:setDefaultHighRepJobPolicyUnappliedJobPercentage(50) – xybrek 2013-04-21 08:28:21

+0

添加wait()不会解决最终一致性,它只会增加获取最新视图的可能性。基本上和做循环一样,就像你已经提到过的那样。 – Strom 2013-04-21 13:05:15

1

如果您在Objectify中需要很强的一致性,那么您可以执行祖先查询see this article for an explanation and examples。但是,这比最终一致的查询更加昂贵,因此尽可能地支持最终一致的查询。

+0

感谢您的回答。我可以生活在最终的一致性中,但不适用于用户相关的查询,最重要的是用于注册系统。 – xybrek 2013-04-21 16:35:35