Advertise with Googlier.comAllan Feid - cache
https://allanfeid.com/category/tags/cache
enImproving varnish hit rates for Drupal 7
https://allanfeid.com/content/improving-varnish-hit-rates-drupal-7
<div class="field field-name-body field-type-text-with-summary field-label-hidden view-mode-rss"><div class="field-items"><div class="field-item even" property="content:encoded"><p>I've recently moved my site to a new VPS and decided to upgrade to Drupal 7 at the same time. It was an interesting move, since a lot of the modules I was using have not yet been ported to D7. One of the main reasons I moved over was for native external caching support, meaning I no longer needed to depend on Pressflow. I ran into a few issues actually getting this to work properly with Varnish, so I wanted to cover how I got this working.</p>
<h2>Changes to Drupal's settings.php</h2>
<p>Just like in Pressflow, you need to make sure the site is aware it is being accessed from behind a reverse proxy:</p>
<pre><code>$conf['reverse_proxy'] = TRUE;
$conf['reverse_proxy_addresses'] = array('127.0.0.1');
</code></pre><p>The next option needed is specific to Drupal 7, and there's a <a href="http://drupal.org/node/804864" title="Clarify the relation between external caching and page_cache_invoke_hooks">bug report</a> to clarify the relation between external caching and <em>page_cache_invoke_hooks</em>. This was a confusing and frustrating part of getting Drupal to set the <em>Cache-Control</em> headers properly.</p>
<pre><code>$conf['page_cache_invoke_hooks'] = FALSE;
</code></pre><p>When you set <em>page_cache_invoke_hooks</em> to false, the cache settings in the UI will be taken into account when sending out the appropriate cache related headers. Without this, you will see <em>Cache-Control: max-age=0</em>, which basically tells Varnish not to cache anything. The bug report explains more in depth as to why this happens.</p>
<h2>A basic VCL for Drupal</h2>
<p>Cookies are usually the biggest issue when it comes to properly caching a website. To find out what cookies were being sent to my backend from Varnish, I started with no custom configuration and picked a URL to test against.</p>
<pre><code>varnishlog -b -o TxURL /content/scaling-your-application-cloud
</code></pre><p>Visit the URL path, and look for a line similar to the following:</p>
<pre><code>11 TxHeader b Cookie: __utmz=148462695.1292604478.3.2.utmcsr=linkedin.com|utmccn=(referral)
|utmcmd=referral|utmcct=/profile/edit; Drupal.toolbar.collapsed=0; has_js=1;
__utma=148462695.668390275.1288311613.1298230598.1298310610.28; __utmc=148462695; __utmb=148462695.11
</code></pre><p>These cookies will cause bad cache hit rates because of the <em>Vary: Cookie</em> header, which tells a compliant reverse proxy, to vary the cache based off of the <em>Cookie</em> header. You can see how this will become an issue, because every browser and client is going to send a different <em>Cookie</em> header. To remove them, you need a line similar to this in the <em>vcl_recv</em> portion of your configuration:</p>
<pre><code>set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js|Drupal.toolbar.collapsed)=[^;]*", "");
</code></pre><p>Most of this comes from the default Pressflow VCL, but a new addition in Drupal 7 is the <em>Drupal.toolbar.collapsed</em> cookie. This cookie seems to be set in order to control toolbar visibility, per the <a href="http://api.drupal.org/api/drupal/modules--toolbar--toolbar.module/7/source" title="toolbar.module documentation">module documentation</a>.</p>
<p>My full VCL is as follows:</p>
<pre><code>backend default {
.host = "127.0.0.1";
.port = "8080";
}
sub vcl_recv {
remove req.http.X-Forwarded-For;
set req.http.X-Forwarded-For = client.ip;
// from https://wiki.fourkitchens.com/display/PF/Configure+Varnish+for+Pressflow?focusedCommentId=13828160
// Remove has_js, Google Analytics __* and Drupal.toolbar.collapsed cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js|Drupal.toolbar.collapsed)=[^;]*", "");
// Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
// Remove empty cookies.
if (req.http.Cookie ~ "^\s*$") {
unset req.http.Cookie;
}
// fix compression per http://www.varnish-cache.org/trac/wiki/FAQ/Compression
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
# No point in compressing these
remove req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate" && req.http.user-agent !~ "MSIE") {
set req.http.Accept-Encoding = "deflate";
} else {
# unkown algorithm
remove req.http.Accept-Encoding;
}
}
}
sub vcl_hash {
if (req.http.Cookie) {
set req.hash += req.http.Cookie;
}
}
</code></pre><p>Once I dropped this VCL in, I started seeing much higher hit rates, which can be viewed on <a href="http://hendrix.crazed.pl/crazed.pl/hendrix.crazed.pl/varnish_hit_rate.html" title="Varnish hit rates">my munin stats page</a>. Prior to implementing the VCL, I was seeing low rates (< 10%) but didn't have the time to troubleshoot until this weekend. I learned a bunch about using <em>varnishtop</em> and <em>varnishlog</em> to find signs as to why my requests weren't being properly cached. I highly recommend checking out the <a href="http://www.varnish-cache.org/docs/2.1/tutorial/increasing_your_hitrate.html" title="Achieving a high hitrate">documentation on achieving higher hit rates</a>.</p>
</div></div></div><section class="field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-above view-mode-rss"><h2 class="field-label">Tags: </h2><ul class="field-items"><li class="field-item even"><a href="/category/tags/sysadmin" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">sysadmin</a></li><li class="field-item odd"><a href="/category/tags/varnish" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">varnish</a></li><li class="field-item even"><a href="/category/tags/cache" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">cache</a></li><li class="field-item odd"><a href="/category/tags/drupal" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Drupal</a></li></ul></section>Mon, 21 Feb 2011 19:25:55 +0000Allan Feid72 at https://allanfeid.com