如何知道Google AppEngine HRD数据存储的更新何时完成?

5
我有一个长时间运行的作业,更新了1000个实体组。我想在此之后启动第二个作业,假设所有这些项目都已更新。由于有如此多的实体组,我无法在事务中完成它,所以我只是使用任务队列安排第二个作业在第一个完成后15分钟运行。

有更好的方法吗?

假设15分钟后数据存储与我的先前调用同步,这样安全吗?

我正在使用高复制。

在关于HRD的Google IO视频中,他们提供了一些处理最终一致性的方法列表。其中之一是“接受它”。一些更新(如Twitter帖子)不需要与下一次读取一致。但他们还说了一些像“嘿,我们只谈论毫秒到几秒钟,然后它们就会一致”。这个时间范围在其他地方有记录吗?等待写入后1分钟再次阅读是否意味着所有先前的写入都在读取中?

这段视频中提到的时间点是39分30秒 http://www.youtube.com/watch?feature=player_embedded&v=xO015C3R6dw


我已经给出了部分答案,但是你能否提供更多关于你具体想要做什么的信息? - mjaggard
基本上我正在插入或更新数千个实体。当该作业完成后,我需要对这些项目应用排名。因此,我运行一个查询,选择所有记录并按照我关心的排名字段进行排序。然后我在另一种实体类型中更新排名。如果查询中缺少实体,则该排名显然会出错。 - user963263
3个回答

0

我认为没有内置的方法来确定更新是否完成。我建议在实体中添加一个lastUpdated字段,并在第一个作业中进行更新,然后在运行第二个作业之前检查要更新的实体上的时间戳...有点像黑客但应该可以工作。

很想看看是否有更好的解决方案。希望他们有;-)


0

只要在获取实体时不改变一致性为“最终”,这就是自动的。HRD会将数据放入大多数相关的数据存储服务器中,然后返回结果。如果您调用异步版本的put,则需要在完成之前对所有Future对象调用get。

但是,如果您查询第一个作业中的项目,则无法确定索引是否已更新。

例如...

如果您正在更新每个实体上的属性(但不创建任何实体),然后检索该种类的所有实体。您可以执行仅键查询,然后进行批量获取(与执行普通查询几乎一样快/便宜),并确保已应用所有更新。

另一方面,如果您正在添加新实体或在第二个进程查询的第一个进程中更新属性,则无法确定。


我的第一个进程既更新又创建新的实体。因此,无论我等待多长时间来执行第二个进程(15分钟或15天),都无法确定这些实体是否会在从数据存储区读取这些相同项的即时调用中出现。 - user963263
这取决于你所说的“读取”的含义 - 如果你的意思是“获取”,那么是的,它们将始终存在。但是,如果你的意思是“查询”或“查找”,那么不行。但是,你可以为每个已添加的实体执行一个仅键查询 - 只有在查询结果中存在每个添加的实体后,才允许执行第二个过程。 - mjaggard
你的意思是将1000个或更多的项目持久化或更新,并将它们的键保留在内存中。然后,当我通过查询读取它们时,请确保所有键都存在于结果中?如果存在,数据是否保证与几秒前运行的更新同步?即使这是一种有效的方法,但在某些时候,我的1000个项目将变成100万个项目,我希望避免在内存中保存那么多的数据。现在,我正在通过使用游标并一次只操作少量项目来避免这种情况。 - user963263
我是指保留您添加的项目列表。如果这可能是100万个项目,那么可以理解,但我假设尽管您可能正在更新大型数据集,但新项目的数量最多也很大。 - mjaggard

0

我找到了这个声明:

使用最终一致性,超过99.9%的写入在几秒钟内可用于查询。

在此页面底部: http://code.google.com/appengine/docs/java/datastore/hr/overview.html

因此,对于我的应用程序来说,下一次读取时它不在那里的可能性为0.1%可能是可以接受的。但是,我计划重新设计我的模式以利用祖先查询。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接