我正在寻找有关Google App Engine平台上常见问题的建议,以保持一致的计数器。 我有一项任务是加载域组,然后为每个组创建一个任务,以便在单独的任务中加载其组成员。现在有成千上万的团体和成员,任务太多了。 我将创建一个任务来获取一个组的页面,在该任务中,我将为每个组创建多个任务以获取其成员。现在,要知道我是否已加载所有组,我有逻辑来检查nextPageToken然后设置加载到已完成的组的标志。
但是,由于每个组都有单独的任务来加载成员,因此我需要跟踪所有组成员任务是否已完成。现在我遇到一个问题,即访问numGroupMembersFinished的单个计数的各种任务将产生并发问题,并且计数将被破坏并且不会返回正确的数据。
答案 0 :(得分:2)
我的回答是一般性的,因为您的问题没有任何代码或建议的解决方案,因为您没有说明您计划保留该计数器的位置。
网上的很多文章都涵盖了这一点。 Google for"分割计数器"用于半可伸缩的方式,在O(1)时间内快速计算数据存储区实体。
更重要的是看一下memcache api。它具有原子递增/递减存储在那里的计数器的功能。保证永远不会出现并发问题,但是你仍然需要一些方法来恢复和/或仔细检查memcache条目是否被驱逐,也许还要保持计数存储在你异步设置的实体中。 "按键获取"始终获得最新价值。
这仍然不是100%防弹,因为缓存可能会在您有许多并发尝试修改它的同时被驱逐,因此您的备份数据存储实体可能会错过&#34; set&#34;。< / p>
您需要根据预期的并发使用情况计算出错过增量/减量的机会是否大于撞击地球的彗星。希望你不要在空中交通管制员上使用它。
答案 1 :(得分: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 Scale上构建数据管道:
答案 2 :(得分:0)
Zig Mandel提到它,这是谷歌自己实施计数器的方法的链接:
https://cloud.google.com/appengine/articles/sharding_counters
我将可配置的分片计数器复制粘贴(重命名了一些变量等等)到我的应用程序中,它运行得很好!
答案 3 :(得分: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)
对于其他语言,同样的方法应该很容易。