我应该使用任务队列将文档添加到AppEngine的索引中吗



通常的情况是:我有一个由数据存储支持的com.google.appengine.api.search.Index。对于每个文档,documentId都是某个实体的键。(为了可视化,假设我有一个产品"表",每个产品都有很多评论。所以每个文档都是一个带有描述性数据和附带评论的产品。所以…)

所以,对于那些知道的人来说,每次更新文档基本上都是在重新创建它。我希望每次用户添加评论时都更新文档。但我想避开比赛条件。但是,如果我使用任务队列,我将如何设计它?与中一样,它应该是单个队列还是多个队列?如果有多个队列,如何避免数据交织?也就是说,两个不同的队列同时更新同一个文档?

我假设每次添加新的review时,您都会更新产品实体(也许您在product主体中有review键的列表)?

我不确定我是否理解"多队列"方法,但如果在数据存储事务中更新产品实体,则可以将重新创建文档的任务排入队列。这样,您可以确保只有在产品成功更新并且文档的更新可以串行化的情况下,文件才"更新"。

这假设您在产品实体上没有太多争论。

写入数据存储时避免竞争条件的答案与传统数据库相同:事务。你可以很容易地使用交易来绕过你提出的种族条件。不需要使用任务队列。交易将确保,如果您的产品在操作过程中更新,您的操作将失败。Objectify(这是一个很好的选择)将自动重试。

不过,如果您担心写争用,首先要知道的是:数据存储无法在单个实体(甚至实体组)上处理太多写吞吐量。如果您需要每秒处理一到两次以上的写入,则需要拆分数据。在您的示例中,我认为您应该将每个注释存储为一个单独的实体。这将消除所有写争用。您只需要在注释中包含产品的ID,并确保该字段已编入索引。然后,当您需要一个产品及其注释时,您可以同时查询所有这些注释。

此外,仅供参考,单个任务队列并不意味着一次只执行该队列中的一个任务(除非您专门设置为这样)。有多种选项可用于限制队列通过任务的速率。文档在这里。

最新更新