-
Website
http://www.eflorenzano.com/ -
Original page
http://www.eflorenzano.com/blog/post/tagging-cache-keys-o1-batch-invalidation/ -
Subscribe
All Comments -
Community
-
Top Commenters
-
traviscooper
1 comment · 2 points
-
pppoll37
7 comments · 1 points
-
linhanyi
2 comments · 1 points
-
dobrych
2 comments · 3 points
-
bosveld
1 comment · 1 points
-
-
Popular Threads
Other than that great method. IMO strong cache invalidation improves caching a lot. Especially for more web-applicationy projects than CMSs.
Anyway, this does not seem problematic unless you use this technique to store session data in cache.
Then, when I want to invalidate all cache associated with a user, I just increment the counter.
In terms of database hits, it's about the same, since you just pass in the cache key rather than the user id when fetching cache.
A -> gets hash 0x01
B -> deletes hash 0x01 because favorites changed
A -> gets favorites-37-None-None-0x01, which is invalid
Good tip, and yeah, the "race condition" is not really a race condition. It's more like a fact of life when using a cache. Sometimes, things just won't be that fresh. This approach goes a long way towards minimizing the number of times that would actually happen.
Re: race conditions, what you're generally after with this sort of caching is read-your-write consistency (if I write data then immediately read it, the read should be consistent) and eventual consistency (eventually everybody should get a consistent view of the data). So the only type of race condition that matters, IMO, is the type where you risk _storing_ stale data in a location that makes it look like _new_ data. Your naive solution was actually susceptible to this (the delete could happen between the get and the set), but as far as I can tell your cache tag solution is not - the worst that could happen is that stale data is stored after invalidation under an old cache key.
http://terrychay.com/blog/article/keeping-memca...
Useful concepts that you can consider.
That way you can invalidate a particular pages content by simply deleting the headers from the cache by request.path (and settings.CACHE_MIDDLEWARE_KEY_PREFIX). Something like
views.decorators.cache.cache_header.%s.%s' % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, iri_to_uri(request.path))
Unrelated to what you're doing it also has the added benefit of invalidating the cached page if the headers change (such as Vary,Cookies etc.). It should probably act like an upstream cache and look at he Vary headers and act accordingly but it works well as is.
But assuming anyone is still reading, you might want to consider a technique by which you invalidate and re-build out of band or you're subject to a thundering herd problem.