Introduction to Varnish

Varnish works as a high-performance and heavily threaded HTTP accelerator using
virtual memory to cache dynamic and content-heavy web-sites. It was designed to
reduce number of system calls and competition between threads to a minimum.


* Packages

  - varnish
  - varnish-libs
  - gcc


* Varnish configuration - backend and inbound request configuration.

  Varnish configuration mechanism is VCL - Varnish Configuration Language.
Loaded VCL script is translated into C, compiled as a shared object, and linked
directly into the accelerator. The VCL files are divided into subroutines that
are executed at different times of processed request.


  File: /etc/varnish/default.vcl
  backend default {
      .host = "127.0.0.1";
      .port = "8080";
  }

  # Subroutine called at the beginning of a request that decides whether or not
  # to serve the request.
  sub vcl_recv {
        # Grace period.
        set req.grace = 5m;

        # Add ping url to test Varnish status.
        if (req.request == "GET" && req.url ~ "/ping") {
                error 200 "OK";
        }

        # Exclude Munin from the cache.
        if (req.url ~ "^/munin/") {
                return (pass);
        }

        # Send request to the specific backend.
        if (req.url ~ "^/bb2/") {
                set req.backend = default;
        }

	# Look for images in the cache and unset cookies - if the client sends
	# a Cookie header, Varnish will bypass the cache and go directly to the
	# backend.
        if (req.url ~ "\.(png|gif|jpg|ico|jpeg|swf|css|js)$") {
                unset req.http.cookie;
                return (lookup);
        }

        return (lookup);
  }


  File: /etc/sysconfig/varnish
  DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -u varnish -g varnish \
             -s file,/var/lib/varnish/varnish_storage.bin,128M"


* Testing Varnish from the command line.

  shell> varnishd -f /etc/varnish/default.vcl -u varnish -g varnish \
    -s malloc,128M -T 127.0.0.1:6082 -a 0.0.0.0:6081


  - Display HTTP Headers
  shell> curl -I http://127.0.0.1:6081/
  HTTP/1.1 200 OK
  Server: Apache/2.2.3 (CentOS)
  X-Powered-By: PHP/5.1.6
  X-Pingback: http://173.203.217.6/xmlrpc.php
  Content-Type: text/html; charset=UTF-8
  Content-Length: 7652
  Date: Mon, 26 Jul 2010 21:18:12 GMT
  X-Varnish: 1666635219
  Age: 3
  Via: 1.1 varnish
  Connection: keep-alive


  - Display generated C code 
  shell> varnishd -C -f /etc/varnish/default.vcl 


* Apache HTTP server configuration.

  File: /etc/httpd/conf/httpd.conf
  Listen 127.0.0.1:8080


* Starting Varnish as a daemon.

  shell> chkconfig varnish on
  shell> service varnish start


* Monitoring.

  - Display and write Varnish logs to a file.
  shell> service varnishlog start

  Log file: /var/log/varnish/varnish.log


  - Display and write Varnish logs to a file in Apache / NCSA combined log
format.
  shell> service varnishncsa start

  Log file: /var/log/varnish/varnishncsa.log


  Note: All log data is stored in shared memory that allows to reduce number
of system calls to minimum. All logging tasks are delegated to a separate
application.


  - Display Varnish logs.
  shell> varnishlog


  - Display traffic between Varnish and the backend servers - optimize cache hit
rates.
  shell> varnishlog -b


  - Display traffic between Varnish and clients.
  shell> varnishlog -c


  - Display Varnish log entry ranking.
  shell> varnishtop
  shell> varnishtop -i rxurl


  - Display Varnish request histogram.
  shell> varnishhist


  - Display Varnish statistics.
  shell> varnishstat


  - Connect to the management interface - control running Varnish instance.
  shell> telnet 127.0.0.1 6082
  shell> varnishadm -T 127.0.0.1:6082 help

  shell> varnishadm -T 127.0.0.1:6082 vcl.load vcl_recv /etc/varnish/default.vcl


* Configuring Munin a network monitoring tool.

Munin is a networked resource monitoring tool that can regularly poll
information from the varnishstat tool and create Varnish web accelerator graphs.

  Directory: /etc/munin/plugins

  varnish_backend_traffic symlink to /usr/share/munin/plugins/varnish_
  varnish_expunge symlink to /usr/share/munin/plugins/varnish_
  varnish_hit_rate symlink to /usr/share/munin/plugins/varnish_
  varnish_memory_usage symlink to /usr/share/munin/plugins/varnish_
  varnish_objects symlink to /usr/share/munin/plugins/varnish_
  varnish_request_rate symlink to /usr/share/munin/plugins/varnish_
  varnish_threads symlink to /usr/share/munin/plugins/varnish_
  varnish_transfer_rates symlink to /usr/share/munin/plugins/varnish_
  varnish_uptime symlink to /usr/share/munin/plugins/varnish_


* Testing performance.

  - Apache

shell> ab -n 32 -c 16 http://127.0.0.1:8080/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient).....done


Server Software:        Apache/2.2.3
Server Hostname:        127.0.0.1
Server Port:            8080

Document Path:          /
Document Length:        0 bytes

Concurrency Level:      16
Time taken for tests:   4.476072 seconds
Complete requests:      32
Failed requests:        0
Write errors:           0
Non-2xx responses:      32
Total transferred:      8928 bytes
HTML transferred:       0 bytes
Requests per second:    7.15 [#/sec] (mean)
Time per request:       2238.036 [ms] (mean)
Time per request:       139.877 [ms] (mean, across all concurrent requests)
Transfer rate:          1.79 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.7      0       1
Processing:   394 1142 615.2   1177    2936
Waiting:      394 1141 615.5   1177    2935
Total:        394 1143 615.4   1178    2936

Percentage of the requests served within a certain time (ms)
  50%   1178
  66%   1237
  75%   1495
  80%   1538
  90%   1666
  95%   2935
  98%   2936
  99%   2936
 100%   2936 (longest request)


  - Varnish

shell> ab -n 32 -c 16 http://127.0.0.1:80/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient).....done


Server Software:        Apache/2.2.3
Server Hostname:        127.0.0.1
Server Port:            80

Document Path:          /
Document Length:        358 bytes

Concurrency Level:      16
Time taken for tests:   0.160520 seconds
Complete requests:      32
Failed requests:        0
Write errors:           0
Non-2xx responses:      32
Total transferred:      24800 bytes
HTML transferred:       11456 bytes
Requests per second:    199.35 [#/sec] (mean)
Time per request:       80.260 [ms] (mean)
Time per request:       5.016 [ms] (mean, across all concurrent requests)
Transfer rate:          149.51 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    8  12.5      0      32
Processing:    20   59  21.2     59      99
Waiting:       19   57  22.3     58      99
Total:         33   67  19.0     69     106

Percentage of the requests served within a certain time (ms)
  50%     69
  66%     76
  75%     82
  80%     83
  90%     88
  95%     99
  98%    106
  99%    106
 100%    106 (longest request)


* Optimizing and tuning Varnish configuration.

  - Identify the most popular URLs.
  shell> varnishtop -i txurl

  - Write log entires including communication with a client.
  shell> varnishlog -c -o /foo/bar

  - Analyzing request headers.
  shell> curl -I http://localhost/


  - Review VCL configuration file.

  File: /etc/varnish/default.vcl
  sub vcl_recv {
        # Drop all cookies send to Wordpress
        unset req.http.cookie;
        return (lookup);
  }

  # Subroutine called after a document has been retrieved from the backend.
  sub vcl_fetch {
        # Drop all cookies send to client
        unset obj.http.set-cookie;
        return (deliver);
  }


  - Testing new configuration.

shell> ab -n 32 -c 16 http://127.0.0.1:80/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient).....done


Server Software:        Apache/2.2.3
Server Hostname:        127.0.0.1
Server Port:            80

Document Path:          /
Document Length:        7652 bytes

Concurrency Level:      16
Time taken for tests:   0.4938 seconds
Complete requests:      32
Failed requests:        0
Write errors:           0
Total transferred:      254368 bytes
HTML transferred:       244864 bytes
Requests per second:    6480.36 [#/sec] (mean)
Time per request:       2.469 [ms] (mean)
Time per request:       0.154 [ms] (mean, across all concurrent requests)
Transfer rate:          50222.76 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.7      0       1
Processing:     0    1   0.8      1       2
Waiting:        0    0   0.3      0       1
Total:          1    1   0.9      2       2
WARNING: The median and mean for the total time are not within a normal
deviation
        These results are probably not that reliable.

Percentage of the requests served within a certain time (ms)
  50%      2
  66%      2
  75%      2
  80%      2
  90%      2
  95%      2
  98%      2
  99%      2
 100%      2 (longest request)


* References
  - Wikipedia, Varnish, http://en.wikipedia.org/wiki/Varnish_%28software%29
  - Varnish, http://varnish-cache.org/
  - Varnish features explained, http://varnish-cache.org/wiki/VarnishFeatures
  - Varnish Tutorial, http://varnish-cache.org/docs/tutorial/
  - Varnish Configuration Language - VCL,
    http://varnish-cache.org/docs/tutorial/vcl/
  - Frequently asked questions about Varnish, http://varnish-cache.org/wiki/FAQ
  - Varnish Software, http://www.varnish-software.com/

  - VCL Examples, http://varnish-cache.org/wiki/VCLExamples
  - Load balancing with Varnish, http://varnish-cache.org/wiki/LoadBalancing
  - Compression support in Varnish,
    http://varnish-cache.org/wiki/FAQ/Compression
  - Preparing Varnish/Wordpress for a Slashdotting in 60 seconds or less,
    http://varnish-cache.org/wiki/VarnishAndWordpress

  - Planet Varnish, http://planet.varnish-cache.org/
  - Varnish http accelerator, http://phk.freebsd.dk/pubs/varnish_tech.pdf
  - Varnish - A State of the Art High-Performance Reverse Proxy,
    http://www.oscon.com/oscon2009/public/schedule/detail/10433
  - Using Varnish or VCL for webmasters,
    http://varnish-cache.org/raw-attachment/wiki/VCLExamples/varnish_vcl.pdf
  - Varnish performance tips on linux,
    http://lists.varnish-cache.org/pipermail/varnish-misc/2008-April/001763.html
  - Varnish Performance, http://varnish-cache.org/wiki/Performance
  - Varnish VCL for UrbanMinistry.org - Tips and Tricks,
    http://groups.drupal.org/node/63203
  - Nginx, Varnish, HAProxy, and Thin/Lighttpd,
    http://blog.hamzahkhan.com/?p=82
  - Magento performance optimization with Varnish cache,
    http://www.kalenyuk.com.ua/magento-performance-optimization-with-varnish-cache-47.html
  - server setup with nginx, php5, fastcgi, varnish,
    http://faruk.akgul.org/blog/entry/server-setup-with-nginx-php5-fastcgi-varnish 
  - Kristian Lyngstol's Blog, http://kristianlyng.wordpress.com/


  - Varnish, Notes from the Architect,
    http://varnish-cache.org/wiki/ArchitectNotes
  - You're doing it wrong, http://queue.acm.org/detail.cfm?id=1814327

  - EPEL software repository,
    http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm


* Author:	Marcin Pawelkiewicz
* Created:	Fri Jul 16 11:05:00 BST 2010
* Modified:	Thu Nov  4 17:21:36 GMT 2010