简体   繁体   English

Google App Engine计数器

[英]Google App Engine counters

For all my data in the GAE Datastore I have a model for keeping track of counters/total number of records (since we can't use traditional SUM queries). 对于GAE数据存储区中的所有数据,我有一个用于跟踪计数器/记录总数的模型(因为我们不能使用传统的SUM查询)。 I want to know the most efficient way of incrementing these global count values whenever I insert/delete a record. 每当我插入/删除记录时,我想知道增加这些全局计数值的最有效方法。 This is what I'm currently doing: 这就是我目前正在做的事情:

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

But this seems quite sloppy to me. 但这对我来说似乎很草率。 Any thoughts on a better way to do this? 有没有想过更好的方法呢?

There are a few issues with your approach: 您的方法存在一些问题:

  • It may under-count since you don't use a transaction to atomically update the counter. 由于您不使用事务以原子方式更新计数器,因此可能计数不足。
  • It is inefficient: 效率低下:
    • Contention may become a problem if you need to update this counter frequently. 如果您需要经常更新此计数器,争用可能会成为问题。 Since you only have one counter, it won't scale well. 由于您只有一个计数器,因此无法很好地扩展。 Datastore entities can only be written at a rate of at most 5 times per second. 数据存储区实体只能以每秒最多5次的速率写入。
    • You're writing to the datastore twice every time you insert a record. 每次插入记录时,您都要写入数据存储区两次。 If you end up using transactions to fix the above problem, then you'll be making two round-trips to the datastore every time you insert the record (once to insert, and once to update the counter). 如果您最终使用事务来解决上述问题,那么每次插入记录时(每次插入一次,一次更新计数器),您将对数据存储区进行两次往返。 You might be able to use an approach which avoids this extra round-trip to the datastore. 您可以使用一种方法来避免这种额外的数据存储往返。

Here are some alternate approaches (from least accurate [and fastest] to most accurate [and slowest]): 以下是一些替代方法(从最不准确[和最快]到最准确[和最慢]):

  • If you only need a rough count of the number of entities of particular kind in the datastore, then you can use the Stats API . 如果您只需要粗略计算数据存储区中特定类型的实体数量,那么您可以使用Stats API The counts you retrieve are not constantly updated, however. 但是,您检索的计数不会不断更新。
  • If you need more granularity but are okay with a small possibility of occasionally under-counting, then you could use a memcache-enhanced counter. 如果你需要更多的粒度,但是偶尔计数不足的可能性很小,那么你可以使用一个memcache增强的计数器。 There are several good implementations discussed in this question . 这个问题中讨论了几个很好的实现。 In particular, see the code in the comments in this recipe . 特别是,请参阅本食谱中注释中的代码。
  • If you really want to avoid undercounting, then you should consider a sharded datastore counter . 如果您真的想避免计算不足,那么您应该考虑使用分片数据存储计数器 This will eliminate the contention issue from above. 这将从上面消除争用问题。

If you need to keep scalability while counting, you should look into Joe Gregorio's article on sharding counters and DocSavage's implementation of the idea. 如果你需要在计算时保持可扩展性,你应该看看Joe Gregorio关于分片计数器和DocSavage 实现这个想法的文章。

AppEngineFan's excellent blog also has info on scalable non-sharded counters, see this one which uses task queues and points to the previous article on using cron jobs instead. AppEngineFan的优秀博客也提供有关可扩展非分片计数器的信息,请参阅此一个使用任务队列并指向上一篇关于使用cron作业的文章。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM