谷歌应用引擎计数器

2024-10-01 04:54:43 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

但这对我来说似乎太草率了。有什么更好的办法吗?在


Tags: 数据方法模型记录counter计数器传统全局
2条回答

你的方法有几个问题:

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

以下是一些替代方法(从最不精确[最快]到最准确[和最慢]):

  • 如果只需要粗略统计数据存储中特定种类实体的数量,那么可以使用Stats API。但是,您检索到的计数不会不断更新。在
  • 如果您需要更大的粒度,但偶尔可能会少计,那么您可以使用memcache增强型计数器。在this question中讨论了几个好的实现。具体来说,请参见this recipe中注释中的代码。在
  • 如果你真的想避免少计,那么你应该考虑一个sharded datastore counter。这将从上面消除争用问题。在

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

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

相关问题 更多 >