Varnish clearing cache objects

Posted by on Jul 27, 2013 in Varnish | No Comments

When you update content you need to update the content of the cache otherwise you will be serving old content even though there is new content available.  There are a couple of different ways which you can refresh the content of the varnish cache.

  • Purging the content from the cache
  • Banning objects from the cahce
  • Forcing a refresh of the page

Purging varnish cache

To use the purge in varnish you need to do this from the VCL, so the easiest way is to send in a HTTP request to purge the object and pick this up in the VCL and process it.  The following is a simple bit of code that you can put in your VCL configuration:

You should create an access list which is a list of addresses that are allowed to send in the requests for clearing the cache.


acl purge {
# For now, I'll only allow purges coming from localhost
"127.0.0.1";
"localhost";
}

In the vcl_recv section


# Allow purging
 if (req.request == "PURGE") {
 if (!client.ip ~ purge) {
 # Not from an allowed IP? Then die with an error.
 error 405 "This IP is not allowed to send PURGE requests.";
 }

# If you got this stage (and didn't error out above), do a cache-lookup
 # That will force entry into vcl_hit() or vcl_miss() below and purge the actual cache
 return (lookup);

 }

The vcl_hit section


sub vcl_hit {
 if (req.request == "PURGE") {
 purge;
 error 200 "Purged";
 }
}

The vcl_miss section

sub vcl_miss {
 if (req.request == "PURGE") {
 purge;
 error 404 "Not in cache";
 }
}

The vcl_pass section

sub vcl_pass {
 if (req.request == "PURGE") {
 error 502 "PURGE on a passed object";
 }
}

Sending in the purge request

Now to send in the PURGE request I find that curl is very useful, the following command will then send in a PURGE request with the URL that you specify


curl -X PURGE <URL>

e.g.


curl -X PURGE http://www.binaryforest.com/server-monitoring/

You will then get back a simple HTML result which will let you know the status of the purge, either it was purged or wasn’t found in the cache e.g.


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
 <head>
 <title>200 Purged</title>
 </head>
 <body>
 <h1>Error 200 Purged</h1>
 <p>Purged</p>
 <h3>Guru Meditation:</h3>
 <p>XID: 2593954</p>
 <hr>
 <p>Varnish cache server</p>
 </body>
</html>

Banning varnish cache objects

You can also add bans which are similar to PURGE requests but these match against the regular expression rather than a specific URL.  You can bans  using VCL as well by adding a processor like we did for the PURGE above.

The following VCL snippet should be added to vcl_recv


if (req.request == "BAN") {
 if (!client.ip ~ purge) {
 # Not from an allowed IP? Then die with an error.
 error 405 "This IP is not allowed to send PURGE requests.";
 }
 ban("req.http.host == " +req.http.host+" && req.url ~ "+req.url);
 error 200 "Ban added";
 }

This will return the same type of output as the PURGE, a simple webpage saying the Ban was added.  You will then be able add elements to the Varnish ban list using similar curl command


curl -X BAN <URL>

e.g.


curl -X BAN http://www.binaryforest.com/server-monitoring/

This will then add that ban to the Varnish ban list.

Refreshing content

If you just want to refresh the content of a page with the most up to date version from the backend, you can also add some code to your VCL which will force the recollection of the page and updating of the cache.

You can add the following to vcl_rec


if (req.request == "REFRESH") {
 if (!client.ip ~ purge) {
 # Not from an allowed IP? Then die with an error.
 error 405 "This IP is not allowed to send PURGE requests.";
 }
 set req.request = "GET";
 set req.hash_always_miss = true;
 }

Now when you perform a REFRESH request it will force the request to miss the cache and thus be sent to the backend which will then refresh the content of the Varnish cache.  The following is a sample REFRESH request using curl:


curl -X REFRESH http://www.binaryforest.com/server-monitoring/

The output that you will see from this is the content of the webpage that was fetched from the backend, your cached version of this page will now also be the latest.

Leave a Reply