Java 处理数据存储最终一致性的技术
GAE的现有持久性框架(如Objectify、Datanucleus、Twig等)如何处理数据存储的“最终一致性”性质 我正在使用Java 处理数据存储最终一致性的技术,java,google-app-engine,nosql,Java,Google App Engine,Nosql,GAE的现有持久性框架(如Objectify、Datanucleus、Twig等)如何处理数据存储的“最终一致性”性质 我正在使用DatastoreService层中的数据存储(我现在没有使用这种持久性框架) 在我的单元测试中,我有时得到正确的对象计数,有时没有。这是意料之中的 这是我的JUnit助手配置: private final LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalDatastore
DatastoreService
层中的数据存储(我现在没有使用这种持久性框架)
在我的单元测试中,我有时得到正确的对象计数,有时没有。这是意料之中的
这是我的JUnit助手配置:
private final LocalServiceTestHelper helper =
new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig()
.setDefaultHighRepJobPolicyUnappliedJobPercentage(50));
现在,即使我将put/get方法放置在一个do-while循环中并重试(重试次数为4),它仍然会错过put/get实体
所以现在,对于那些指定的框架,他们是否能够保证,如果我放置3个对象,我将得到3个对象?如果是,它是如何实施的
我能想到的唯一一件事就是使用Memcache,也就是说,我的方法将尝试首先从中获取实体,如果它错过了,它将只检查数据存储。这是一个合理的方法,还是有更好的方法或正确的方法?Objectify不以任何方式、形状或形式处理最终的一致性。作为开发人员,在使用Objectify或任何其他库时必须记住这一点 围绕查询执行do/while循环,或添加wait()都不能保证强一致性。你最多只能增加获得最新结果的概率,但这还远远不能确定 Memcache在这里也没有提供任何保证,因为它是不可靠的存储。memcache put()函数是不可操作的,也就是说,什么都不做是完全合法的
为了解决您的核心问题,您需要以使用强一致性的方式设计应用程序。因此,您可以使用强一致性数据存储读取操作,如gets或祖先查询。或者您可以通过HTTP传递一些数据。如果您需要Objectify中的强一致性,那么您可以执行祖先查询。但是,这比最终一致性查询更昂贵,因此尽可能支持最终一致性查询。如果您希望查询具有强一致性,则有两种选择:
如果仔细构造键名,通常可以使用GET而不是查询。如果您需要查询对给定用户“显示”一致,那么您的另一个选择是应用一个小技巧:将用户的更改注入到结果中。因此,如果他们更改了姓名,而您重定向到了他们的个人资料页面,请在发送之前将他们的更改注入结果。是否会花费高昂的成本来缓存每个put和get?在内存和cpu方面?您建议的缓存方法如何处理集群应用程序?(多个实例读取和写入相同的记录)所以在我的单元测试中,我必须执行一个wait()方法,你认为这样可以吗?我的意思是,我希望它不会失败一次,设置为:setDefaultHighRepJobPolicyUnpliedJobPercentage(50)添加wait()并不能解决最终的一致性问题,它只会增加获取最新视图的可能性。基本上和你刚才提到的做循环一样。谢谢你的回答。我可以接受最终的一致性,但不适用于与用户相关的查询,最重要的是适用于注册系统。好的一点,我记得最失败的是那些基于查询的查询,甚至我使用的PreparedQuery计数方法也失败了。是的,如果你想准确,你必须使用祖先查询。请记住,在某些情况下,使用祖先查询将使用额外的索引,这将意味着写操作的成本略高—无论是在金钱上还是在时间上。