0

我正在寻找有关 Google App Engine 平台上一个非常常见的问题的建议,以保持一致的计数器。我有一个任务来加载域的组,然后为每个组创建一个任务以将其组成员加载到单独的任务中。现在因为有成千上万的组和成员,所以会有太多的任务。我将创建一个任务来获取一页组,并在该任务中为每个组创建多个任务以获取其成员。现在,要知道我是否已加载所有组,我有逻辑检查nextPageToken 然后将组加载的标志设置为已完成。

但是,由于每个组将有单独的任务来加载成员,因此我需要跟踪所有组成员任务是否已完成。现在我遇到了一个问题,即访问单个 numGroupMembersFinished 计数的各种任务会产生并发问题,并且在某个地方计数会损坏并且不会返回正确的数据。

4

4 回答 4

2

我的回答很笼统,因为您的问题没有任何代码或建议的解决方案,因为您没有说明您打算在哪里保留该计数器。

网络上的许多文章都涵盖了这一点。谷歌的“分片计数器”是一种半可扩展的方式,可以在 O(1) 时间内快速计算数据存储实体。

更重要的是看看 memcache api。它具有以原子方式递增/递减存储在那里的计数器的功能。保证永远不会出现并发问题,但是您仍然需要某种方法来恢复和/或仔细检查内存缓存条目是否未被驱逐,也许还可以通过将计数存储在您异步设置的实体中并“获取按键”以始终获取其最新值。

这仍然不是 100% 防弹的,因为缓存可能会在您有许多并发尝试修改它的同时被驱逐,因此您的备份数据存储实体可能会错过“集合”。

您需要根据预期的并发使用情况来计算错过增量/减量的机会是否大于彗星撞击地球的机会。希望您不会在空中交通管制员上使用它。

于 2015-05-01T17:20:56.373 回答
1

您可以使用 MapReduce 或 Pipeline API:

https://github.com/GoogleCloudPlatform/appengine-mapreduce https://github.com/GoogleCloudPlatform/appengine-pipelines

允许您将问题拆分为更小的可管理部分,从而库可以处理任务之间的信号/阻塞的所有细节,收集结果,并在完成后将它们交还给您

Google I/O 2010 - 使用 Google App Engine 的数据管道:

https://www.youtube.com/watch?v=zSDC_TU7rtc

Google I/O 2011:使用 App Engine Pipeline API 进行大规模数据分析:

https://www.youtube.com/watch?v=Rsfy_TYA2ZY

Google I/O 2011:App Engine MapReduce:

https://www.youtube.com/watch?v=EIxelKcyCC0

Google I/O 2012 - 在 Google 规模上构建数据管道:

https://www.youtube.com/watch?v=lqQ6VFd3Tnw

于 2015-05-01T18:11:16.463 回答
0

Zig Mandel 提到了它,这是 Google 自己实现计数器的配方的链接:

https://cloud.google.com/appengine/articles/sharding_counters

我将可配置的分片计数器复制粘贴(重命名了一些变量等)到我的应用程序中,效果很好!

于 2015-05-06T21:44:59.817 回答
0

我使用了本教程:https ://cloud.google.com/appengine/articles/sharding_counters和hashid库并创建了这个 golang 库:

https://github.com/janekolszak/go-gae-uid

gen := gaeuid.NewGenerator("Kind", "HASH'S SALT", 11 /*id length*/)
c := appengine.NewContext(r)
id, err = gen.NewID(c)

对于其他语言,相同的方法应该很容易。

于 2015-06-05T15:50:40.050 回答