What if some data that is saved in varnish cache is changed after sometime on backend server. Then when a request comes, then varnish return old data or updated data?
The old data, or to be clear: it returns the data as it was at the time when it was cached if the expiry time of the cached object has not yet been reached. If you want it to update before that time you need to purge or ban the item in the cache. See the chapter on Purging and banning in the varnish documentation for details on implementation.
Related
I'm trying to use varnish to cache rpms and other giant binaries. What I would've expected is that when an object is expired in the cache varnish would send a request with If-Not-Modified to the backend and then assuming the object didn't change, varnish would refresh the ttl on the local cached object without downloading a new one. I wrote a test backend to generate specific request (set small max-age and whatnot, as well as see the header varnish sends) but I never get anything else then full fetch. If-Not-Modified is never sent. My VCL is basically the default VCL. I tried playing around with setting small ttl/grace but never got any interesting behavior.
Is varnish even able to do what I want it to ? If so has anyone done anything similar and can give tips ?
The request sent to the backend when an object is expired is the one that Varnish receives from the client.
So when testing your setup, are you sending an If-Not-Modified header in your requests to Varnish?
Have a look at https://www.varnish-software.com/wiki/content/tutorials/varnish/builtin_vcl.html to see what the built in VCL is.
Under vcl_backend_fetch, which will be called if there is no object in the cache, you can see there is no complex logic around stale objects, it is just passing on the request as is.
First of all, quite a bit has happened in varnish-cache since this question was posted. I am answering the questions for varnish-cache 6.0 and later:
The behavior the OP expects is how varnish should behave now if the backend returns the Last-Modified and/or Etag headers.
Obviously, an object can only be refreshed if it still exist in cache. This is what beresp.keep is for. It extends the time an object is kept in cache after ttl and grace have expired. Note that objects are also LRU evicted if the cache is too small to keep all objects for their maximum lifetime.
On the comment by #maxschlepzig, it might be based on a misunderstanding:
When an object is not in cache but is to be cached, varnish can not forward the client request's conditional headers (If-Modified-Since, If-None-Match) because a 304 response would not be good for caching (it has not body and is relevant only for a particular request). Instead, varnish strips to conditional headers for this case to (potentially) get a 200 response with an object to put into cache.
As explained above, for a subsequent backend request after the ttl has expired, the conditional headers are constructed based on the cached response. The conditional headers from the client are not used for this case either.
All of this above applies for the case that an object is to be cached at all (Fetch, Hit-for-Miss (as created by setting beresp.uncacheable)).
For Pass and Hit-for-Pass (as created by return(pass(duration)) in vcl_backend_response), the client conditional headers are passed to the backend.
We have a hazelcast problem. For the last few days, it has not been refreshing itself. We have to maunally refresh the cache from the web console.
What can I do about this?
And other problem is: How can I force hazelcast to read from db if cache does not exist?
It is not clear what you mean by Refresh. Normally, what users do is, they have TTL configured for the entries in MAP. And you can also implement a MapStore that will read from DB, when entry is not available in cache. When your applications read the entry and if it doesn't exist in cache, Hazelcast will call the mapstore to read from DB. And after TTL elapsed, the entry will be removed from the cache. Next time you read it, it will be refreshed.
We are trying to implement cache aside pattern on azure. While reading data, we first check if data exist on cache, if it does, we serve it from cache. Otherwise we fetch it from database, populate cache and return it.
If cache is not accessible (due to some transient or non-transient issues), we ignore it.
But in case of update, we first update it in database and then delete the cache key. What should we do in case if cache is not accessible? To handle transient error we can implement retry strategy. If cache is not accessible even after retry, we should rollback our database transaction. Otherwise if cache comes back later, it would not be in sync with db. But while retrying, if somebody try to read this data, he will get a update value can later be rollbacked (if cache is not responding).
Thanks In Advance
If the backend is sick, what is the preferable way to ensure that stale content can be retrieved from the backend when a PURGE request is made?
When a PURGE request is made, whether or not the backend is sick, by default the content will be eliminated from the Varnish cache and if the backend is down, a 503 page would be served to the user until the backend comes back online to serve a new version of the content. I'd like to be able to at least serve up a stale version of the content if a new version could not be retrieved from the backend.
Is this possible without installing the Softpurge Varnish Mod?
No, this is not possible.
Any Varnish 3.0 purge command will set the object TTL so it is seen as expired, and the expiry thread will reclaim the memory within seconds/milliseconds.
The softpurge VMOD does mostly what purge does, but in addition recomputes the grace value so even if it is expired it is not a candidate for eviction by the expiry thread.
I'm using Varnish in front of the backend.
Because the backend is sometimes very slow, I've enabled grace mode to serve stale content for clients. However, with grace mode, there is still one user will need to go to backend and have a very bad user experience.
Is it possible with Varnish to server stale content for ALL users while refreshing the cache?
I've seen some people suggested to use a cron job or script to refresh the cache on local host. This is not an elegant solution because there are so many URLs on our site and it'll be very difficult to manually refresh each of them.
I know the underlying problem is with the backend and we need to fix the problem there. But in the short term, I'm wondering if I can improve response time from Varnish layer?
You can do this (in the average case) in Varnish 3 by using restarts and a helper process.
How you'd write a VCL for it is described here: (disclosure: my own blog)
http://lassekarstensen.wordpress.com/2012/10/11/varnish-trick-serve-stale-content-while-refetching/
It is fairly convoluted, but works when you have an existing object that just expired.
In (future) Varnish 4 there will be additional VCL hooks that will make such tricks easier.
Yes, it is possible to serve stale content to all users (during a specified amount of time). You should experiment with the grace and saint mode to set appropriate time limits that suits your application.
Read more here: https://www.varnish-cache.org/docs/3.0/tutorial/handling_misbehaving_servers.html