HIT after PURGE & Restart

Nigel Peck np.lists at sharphosting.uk
Thu Apr 13 23:26:59 CEST 2017


Thanks for this, really helpful to have the assistance. There's no 
chance that the object was requested between the purge and hit, because 
those log entries are from a simple varnishlog query for the specific URI.

varnishlog -d -q "ReqURL eq '/media/images/logo-glyph-2x.png'"

So it would be shown in the log.

I don't think there's anything in my VCL that is causing this. But I'm 
including it all below in case and to help in diagnosing this.

Regarding the test, Dridi, I wouldn't expect that to fail. This is not 
happening in the majority of cases. But what is happening is that I'm 
monitoring the log for any misses, and noticed that there are 
unexplainable misses sometimes. I have a script that issues a PURGE 
request for every URI on the site, with TTL being set to 7 days, so 
nothing should be getting missed, yet sometimes things are. After a few 
days looking at these misses from various angles, to try and work out 
what's going on, the description in my original message *seems* to be 
what is happening. There is no Vary issue since nothing is varied on, 
and all cookies are removed in VCL_recv. They are definitely being 
cached with the 7d TTL. So there should be no need for a miss.

The real issue for me is the miss on something that has been purged and 
re-cached a short time before, but the purge and subsequent HIT seems to 
be related to the problem.

I just checked the log again and there are no fresh misses since 
yesterday, which confirms the theory that this is related to the PURGE 
and otherwise all ok.

I also included below a second example of the same thing from yesterday. 
It's not a high traffic site, so I may need to spend some more time 
gathering info, but I think I have enough to present to you, hence the 
query. Thanks again.

=======
VCL
(very simple as mentioned)
=======

vcl 4.0;
import std;

# Default backend definition. Set this to point to your content server.
backend default {
     .host = "x.x.x.x";
     .port = "80";
}

# Access list for purging, local only
acl purgers {
     "127.0.0.1";
     "x.x.x.x";
}

# Process any "PURGE" requests converting
# them to GET and restarting
sub vcl_purge {
     set req.method = "GET";
     return (restart);
}

sub vcl_synth {
     # Handle 301 redirects, taking reason as the URL
     # and then replacing it with the standard reason
     # Recommended at:
     # https://varnish-cache.org/tips/vcl/redirect.html
     if (resp.status == 301) {
         set resp.http.location = resp.reason;
         set resp.reason = "Moved Permanently";
         return (deliver);
     }
}

sub vcl_recv {
     # Server_Name was here
     if (req.restarts == 0) {
         set req.http.X-Processed-By = "Server_Name";
     }
     # allow PURGE from localhost and x.x.x.x
     if (req.method == "PURGE") {
         if (!client.ip ~ purgers) {
             return (synth(405, "Purging not allowed for " + client.ip));
         }
         return (purge);
     }
     # Forward client's IP to the backend
     if (req.restarts == 0) {
         if (req.http.X-Real-IP) {
             # Do nothing, we already have all we need recorded
         } elsif (req.http.X-Forwarded-For) {
             set req.http.X-Forwarded-For = req.http.X-Forwarded-For + 
", " + client.ip;
         } else {
             set req.http.X-Forwarded-For = client.ip;
         }
     }
     # Redirect non-HTTPS to HTTPS
     # Identified by the fact it does not have the X-Forwarded-Port header
     if (req.http.X-Forwarded-Port != "443") {
         return (synth(301, "https://www.example.com" + req.url));
     }

     # Unset all cookies
     unset req.http.Cookie;

}

sub vcl_backend_response {

     # Server_Name was here
     set beresp.http.X-Processed-By = "Server_Name";

     # Don't cache 404 responses
     if ( beresp.status == 404 ) {
         set beresp.ttl = 120s;
         set beresp.uncacheable = true;
         return (deliver);
     }

     # Compress appropriate responses
     if (beresp.http.content-type ~ 
"\b((text/(html|plain|css|javascript|xml|xsl))|(application/(javascript|xml|xhtml\+xml)))\b") 
{
         set beresp.do_gzip = true;
     }

     # Set long TTL and grace time for 200 and 304 responses
     if ( beresp.status == 200 || beresp.status == 304 ) {

         # Allow stale content, in case the backend goes down
         set beresp.grace = 6h;

         # This is how long Varnish will keep cached content
         set beresp.ttl = 7d;
     }

}

sub vcl_deliver {
     # Send special headers that indicate the cache status of each response
     if (obj.hits > 0) {
         set resp.http.X-Cache = "HIT";
         set resp.http.X-Cache-Hits = obj.hits;
     } else {
         set resp.http.X-Cache = "MISS";
     }

     return (deliver);
}

=======
Second Example
=======

*   << Request  >> 230660
-   Begin          req 230659 rxreq
-   Timestamp      Start: 1492038071.998363 0.000000 0.000000
-   Timestamp      Req: 1492038071.998363 0.000000 0.000000
-   ReqMethod      PURGE
-   VCL_call       RECV
-   VCL_return     purge
-   VCL_call       HASH
-   VCL_return     lookup
-   VCL_call       PURGE
-   ReqMethod      GET
-   VCL_return     restart
-   Timestamp      Restart: 1492038071.998436 0.000074 0.000074
-   Link           req 230661 restart
-   End

*   << Request  >> 230661
-   Begin          req 230660 restart
-   Timestamp      Start: 1492038071.998436 0.000074 0.000000
-   ReqMethod      GET
-   VCL_call       RECV
-   VCL_return     hash
-   VCL_call       HASH
-   VCL_return     lookup
-   Hit            167648
-   VCL_call       HIT
-   VCL_return     deliver
-   VCL_call       DELIVER
-   RespHeader     X-Cache: HIT
-   RespHeader     X-Cache-Hits: 1
-   VCL_return     deliver
-   Timestamp      Process: 1492038071.998474 0.000112 0.000038
-   Debug          "RES_MODE 2"
-   Timestamp      Resp: 1492038071.998528 0.000166 0.000054
-   Debug          "XXX REF 2"
-   ReqAcct        269 0 269 346 1538 1884
-   End

*   << Request  >> 364940
-   Begin          req 364939 rxreq
-   Timestamp      Start: 1492060849.803654 0.000000 0.000000
-   Timestamp      Req: 1492060849.803654 0.000000 0.000000
-   ReqMethod      GET
-   VCL_call       RECV
-   VCL_return     hash
-   VCL_call       HASH
-   VCL_return     lookup
-   Debug          "XXXX MISS"
-   VCL_call       MISS
-   VCL_return     fetch
-   Link           bereq 364941 fetch
-   Timestamp      Fetch: 1492060849.805443 0.001789 0.001789
-   VCL_call       DELIVER
-   RespHeader     X-Cache: MISS
-   VCL_return     deliver
-   Timestamp      Process: 1492060849.805531 0.001876 0.000087
-   Debug          "RES_MODE 2"
-   RespHeader     Connection: close
-   RespHeader     Accept-Ranges: bytes
-   Timestamp      Resp: 1492060849.805594 0.001939 0.000063
-   Debug          "XXX REF 2"
-   ReqAcct        347 0 347 322 1538 1860
-   End

*   << Request  >> 364994
-   Begin          req 364993 rxreq
-   Timestamp      Start: 1492061706.708306 0.000000 0.000000
-   Timestamp      Req: 1492061706.708306 0.000000 0.000000
-   ReqMethod      GET
-   VCL_call       RECV
-   VCL_return     hash
-   VCL_call       HASH
-   VCL_return     lookup
-   Hit            364941
-   VCL_call       HIT
-   VCL_return     deliver
-   VCL_call       DELIVER
-   RespHeader     X-Cache: HIT
-   RespHeader     X-Cache-Hits: 1
-   VCL_return     deliver
-   Timestamp      Process: 1492061706.708382 0.000076 0.000076
-   Debug          "RES_MODE 2"
-   RespHeader     Connection: close
-   RespHeader     Accept-Ranges: bytes
-   Timestamp      Resp: 1492061706.708417 0.000111 0.000035
-   Debug          "XXX REF 2"
-   ReqAcct        447 0 447 347 1538 1885
-   End

On 13/04/2017 07:45, Dridi Boukelmoune wrote:
> On Thu, Apr 13, 2017 at 8:48 AM, Guillaume Quintard
> <guillaume at varnish-software.com> wrote:
>> Is there any chance that:
>> - someone requested the object between the purge and the subsequent hit?
>> - you re-processed the request again, changing the cache (non-idempotent URL
>> rewrite, maybe?)
> 
> At first glance things look OK on 4.0, 4.1, 5.0 and 5.1:
> 
>      varnishtest "purge+restart should miss"
> 
>      server s1 {
>          rxreq
>          txresp -body first
> 
>          rxreq
>          txresp -body second
>      } -start
> 
>      varnish v1 -vcl+backend {
>          sub vcl_recv {
>              if (req.method == "PURGE") {
>                  return (purge);
>              }
>          }
> 
>          sub vcl_purge {
>              set req.method = "GET";
>              return (restart);
>          }
>      } -start
> 
>      client c1 {
>          txreq
>          rxresp
>          expect resp.body == first
> 
>          txreq -req PURGE
>          rxresp
>          expect resp.body == second
>      } -run
> 
> I will try a more involved test later on.
> 
> Dridi
> 



More information about the varnish-misc mailing list