RavenDB Aggressive Caching Mode
RavenDB has the notion of HTTP caching out of the box, what this means is that by default, without you having to take any action, RavenDB will cache as much as possible for you. It can get away with doing this because it is utilizing the notion of the 304 Not Modified response. The second time that we load an entity or execute a query, we can simply ask the server whatever the data has been modified since the last time we saw it, and if it wasn’t, we can just skip executing the code and get the data directly from the cache.
This saves a lot in terms of bandwidth and processing power, it also means that we don’t have to worry about RavenDB’s caching returning any stale results, because we checked for that. It does mean, however, that we have to send a request to the server. There are situation where we want to squeeze even better performance from the system, and we can move to RavenDB’s aggressive caching mode.
Aggressive caching means that RavenDB won’t even ask the server whatever anything has changed, it will simply return the reply directly from the local cache if it is there. This means that you might get stale data, but it also means that you’ll get it fast.
You can activate this mode using:
using (session.Advanced.DocumentStore.AggressivelyCacheFor(TimeSpan.FromMinutes(5))) { session.Load<User>("users/1"); }
Now, if there is a value in the cache for users/1 that is at most 5 minutes old, we can directly use that.
It also works on queries too:
using (session.Advanced.DocumentStore.AggressivelyCacheFor(TimeSpan.FromMinutes(5)))
{
session.Query<User>().ToList();
}
This is an explicit step beyond the normal caching, and it does mean that you might get out of date information, but if you really want to reduce the number of remote calls, it is a really nice feature.
Comments
I do like the naming. "Aggressively" makes you think about possibilities of misuse or abuse (as with real anger).
Thanks, That was the intent, to make sure that you are well aware of what you are doing.
Ayende, speaking about the aggresive caching. Have you considered 'pushing' the invalidation to the clients, via comet or sth?
I see a little div at the top of your blog that says "RavenDB Profiler". Application integration with the profiler is a pretty cool feature, and this is a neat way to demo it.
yeah.. +1 for that profiler div :) Good stuff!
Schooletz, Not really, no. It doesn't make sense, considering most scenarios. It would be fairly complex to do, too. Consider the case of me updating a document "users/1" with a new email.
How do I tell a client that has cached the query users by email about that?
How do I even figure this out?
Ok, but I have to ask as I'm curious about your opinion: using sth like NHibernate UpdateTimestampsCache, storing last modified ETag for each region/document type, wouldn't it work?
Scooletz, Yes, it could be made to work, in which case it would: * Require complex config when running in web farms. * Complicate explaining how this works. * We don't have tables, and collections are virtual, it means that in some cases, this wouldn't work.
Rather, it is so much simpler to say that if you care about this, don't use aggressive caching, RavenDB already support HTTP caching, and that is safe from all of those issues.
Ayende, I agree that it would add additional complexity (as a matter of fact the RavenEtag usage is awsome and it pushes the consistency across network to the limits), but the third point nailed it: not working in all the scenarios, that's a pity. Thx for your explanation.
Comment preview