【问题标题】:Google App Engine countersGoogle App Engine 计数器
【发布时间】:2011-04-20 11:52:06
【问题描述】:

对于我在 GAE 数据存储中的所有数据,我有一个用于跟踪计数器/记录总数的模型(因为我们不能使用传统的 SUM 查询)。我想知道每当我插入/删除记录时增加这些全局计数值的最有效方法。这就是我目前正在做的事情:

counter = DBCounter.all().fetch(1)
dbc = DBCounter(totalTopics=counter[0].totalTopics+1)
dbc.put()

但这对我来说似乎很草率。对更好的方法有什么想法吗?

【问题讨论】:

    标签: python google-app-engine transactions google-cloud-datastore


    【解决方案1】:

    您的方法存在一些问题:

    • 由于您不使用事务以原子方式更新计数器,因此它可能计数不足。
    • 效率低下:
      • 如果您需要经常更新此计数器,则可能会出现争用问题。由于您只有一个计数器,因此无法很好地扩展。数据存储区实体只能以每秒最多 5 次的速率写入。
      • 每次插入记录时,您都会写入数据存储两次。如果您最终使用事务来解决上述问题,那么您每次插入记录时都会对数据存储进行两次往返(一次插入,一次更新计数器)。您也许可以使用一种方法来避免这种额外的数据存储往返。

    这里有一些替代方法(从最不准确[最快]到最准确[最慢]):

    • 如果您只需要粗略计算数据存储区中特定类型实体的数量,则可以使用Stats API。但是,您检索的计数不会不断更新。
    • 如果您需要更高的粒度,但可以接受偶尔计数不足的可能性很小,那么您可以使用内存缓存增强型计数器。 this question 中讨论了几个很好的实现。具体看this recipe的cmets中的代码。
    • 如果你真的想避免低估,那么你应该考虑sharded datastore counter。这将消除上面的争用问题。

    【讨论】:

      【解决方案2】:

      如果您需要在计数时保持可扩展性,您应该查看 Joe Gregorio 关于 sharding counters 和 DocSavage 的 implementation 的文章。

      AppEngineFan 的优秀博客也有关于可扩展非分片计数器的信息,请参阅this one,它使用任务队列并指向上一篇关于使用 cron 作业的文章。

      【讨论】:

        猜你喜欢
        • 2012-07-24
        • 2014-12-01
        • 2011-08-22
        • 1970-01-01
        • 1970-01-01
        • 2010-11-20
        • 1970-01-01
        • 1970-01-01
        • 2017-03-08
        相关资源
        最近更新 更多