这个问题涉及计数器的两种实现,它们旨在在不分片的情况下进行扩展(在某些情况下它们可能会被低估):
- http://appengine-cookbook.appspot.com/recipe/high-concurrency-counters-without-sharding/(评论中的代码)
- http://blog.notdot.net/2010/04/High-concurrency-counters-without-sharding
我的问题:
- 关于#1:
memcache.decr()
在延迟的事务性任务中运行似乎有点矫枉过正。如果memcache.decr()
在事务之外完成,我认为最坏的情况是事务失败并且我们错过了计算我们减少的任何内容。 我是否忽略了这样做可能会出现的其他问题? - 两种实现之间的重要权衡是什么?
以下是我看到的权衡:
2 不需要数据存储事务。
- 要获取计数器的值,#2 需要获取数据存储,而使用 #1通常只需要执行
memcache.get()
andmemcache.add()
。 - 当增加一个计数器时,两者都调用
memcache.incr()
. 定期,#2 将任务添加到任务队列,而#1 事务性地执行数据存储获取和放置。#1 也总是执行memcache.add()
(以测试是否是时候将计数器持久化到数据存储区)。
结论
(没有实际运行任何性能测试):
1 通常在检索计数器时应该更快(#1 memcache vs #2 datastore)。虽然 #1 也必须执行额外的操作
memcache.add()
。- 但是,在更新计数器时,#2 应该更快(#1 数据存储 get+put 与 #2 使任务入队)。
- 另一方面,对于 #1,您必须更加小心更新间隔,因为任务队列配额几乎比数据存储或 memcahce API 小 100 倍。