Note that there are some explanatory texts on larger screens.

plurals
  1. POHigh-concurrency counters without sharding
    primarykey
    data
    text
    <p>This question concerns two implementations of counters which are intended to scale without sharding (with a tradeoff that they might under-count in some situations):</p> <ol> <li><a href="http://appengine-cookbook.appspot.com/recipe/high-concurrency-counters-without-sharding/" rel="noreferrer">http://appengine-cookbook.appspot.com/recipe/high-concurrency-counters-without-sharding/</a> (the code in the comments)</li> <li><a href="http://blog.notdot.net/2010/04/High-concurrency-counters-without-sharding" rel="noreferrer">http://blog.notdot.net/2010/04/High-concurrency-counters-without-sharding</a></li> </ol> <h3>My questions:</h3> <ul> <li>With respect to #1: Running <code>memcache.decr()</code> in a deferred, transactional task seems like overkill. If <code>memcache.decr()</code> is done outside the transaction, I think the worst-case is the transaction fails and we miss counting whatever we decremented. <em>Am I overlooking some other problem that could occur by doing this?</em></li> <li><em>What are the significiant tradeoffs between the two implementations?</em></li> </ul> <h3>Here are the tradeoffs I see:</h3> <ul> <li><h1>2 does not require datastore transactions.</h1></li> <li>To get the counter's value, #2 requires a datastore fetch while with #1 <i>typically</i> only needs to do a <code>memcache.get()</code> and <code>memcache.add()</code>.</li> <li>When incrementing a counter, both call <code>memcache.incr()</code>. Periodically, #2 adds a task to the task queue while #1 transactionally performs a datastore get and put. #1 also always performs <code>memcache.add()</code> (to test whether it is time to persist the counter to the datastore). </li> </ul> <h3><i>Conclusions</i></h3> <p>(without actually running any performance tests):</p> <ul> <li><h1>1 should typically be faster at retrieving a counter (#1 memcache vs #2 datastore). Though #1 has to perform an extra <code>memcache.add()</code> too.</h1></li> <li>However, #2 should be faster when updating counters (#1 datastore get+put vs #2 enqueue a task).</li> <li>On the other hand, with #1 you have to be a bit more careful with the update interval since the task queue quota is almost 100x smaller than either the datastore or memcahce APIs.</li> </ul>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload