Reputation: 885
Using varnish 4 to cache different content of same request from multiple servers. It looks like it caches the first request from one server and keeps giving the same content for every subsequent request.
doing curl gives response with two caches and different age.
Are there any factors like load or anything else for stickiness behaviour? Used Jmeter and apache benchmark with load but still got the same behaviour.
Is my vcl_hash is good? Want to save the object with hash combination of url and ip of backend server.
Atleast in my case, looks like after the ttl of the cache object, varnish is caching from second server and returns the same until ttl is done. But this is not what we expect it to behave?
am I missing anything?
using round robin and hash_data. below is my config.vcl
backend s1{
.host = "190.120.90.1";
}
backend s2{
.host = "190.120.90.2";
}
sub vcl_init {
new vms = directors.round_robin();
vms.add_backend(s1);
vms.add_backend(s2);
}
sub vcl_recv {
set req.backend_hint = vms.backend();
}
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
return(lookup);
}
Upvotes: 1
Views: 998
Reputation: 2473
First thing to consider is that you are going to have the backend ip only after the object has been fetched from it. So you are not able to use that ip on your hash method because vcl_hash occurs before fetch.
Second is about the round robin. It takes place only when Varnish is fetching the objects, hence it will not take place when an object has already been cached.
To answer your question precisely it is needed to know why your application delivers different content for the same request. How do you indicate which backend is being requested if the request is always the same? There must be something like a cookie, a header or the origin IP of the request that should dictate which one must respond to that request.
Knowing that it is possible to set the specific backend and use it in your vcl_hash. For example purposes, let's assume that you want to set your backends based on the presence of a header named backend_choice
:
sub vcl_recv {
if (req.http.backends_choice == "s1") {
set req.backend_hint = s1;
# If the header is not "s1" or does not exist
} else {
set req.backend_hint = s2;
}
...
}
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
# We use the selected backend to hash the object
hash_data(req.backend_hint);
return(lookup);
}
Hope this answer address your needs. If there was something that I missed, feel free to comment or add to your question and I'll be glad to add some info to my answer.
Upvotes: 3