What is the best way to distribute this load? One way would be to simply distribute it evenly across instances or another be to distribute the load based on the request URL pattern. Is there a best practice for this?
It depends. Two reason you'd want to base distribution on something like a URL hash:
- Cache size. If you're caching enough data overall that you'd fill the cache of a given backend, it would help to have a certain URL always hitting the same backend, to distribute the storage of cache data between backends instead of storing duplicates.
- Speed of a missed request/cache lifetime. If client requests missing cache is a problem and you cache doesn't last long, you'll probably get fewer misses if a given piece of content will always hit a given Varnish server.
Also--we have a situation where we'll need to manually (from the backend) purge specific items from our caches. Is the most effective way to do this simply to issue a small HTTP "PURGE" request to each of our Varnish instances?
That works, but leaves the next requester of the content with a potentially slow cache miss. An alternative is to use Varnish's req.hash_always_miss
to force an update of a resource in cache instead of just invalidating it, so a request from outside won't be forced to miss.
So something like this in your vcl:
acl purge {
"localhost";
}
sub vcl_recv {
/* add this into your existing config: */
if (req.http.X-Varnish-Nuke == "1" && client.ip ~ purge) {
set req.hash_always_miss = true;
}
}
Then a request with that header set will force a backend request to update the content in cache (with curl or wget, --header "X-Varnish-Nuke: 1"
).