What is Varnish?
- “A web application accelerator also known as a caching HTTP reverse proxy.”
- A piece of software that makes dynamic websites really really really fast.
- It sits between the client and the webserver and caches webpages.
Loading a webpage from Drupal
Plain ol' Drupal
- User requests a URL.
- Web server (Apache/Nginx/IIS) sends it to Drupal.
- Drupal bootstraps and initializes the database, sessions etc.
- Maps the path to a callback function, which gets the primary content.
- Modules can hook into the process and extend functionality and alter the content.
- The Theme System generates the HTML and applies styles it to.
- Drupal returns a fully formed HTML page to the browser.
- The browser renders the HTML page for the user.
Drupal with core caching
- User requests a URL.
- Web server (Apache/Nginx/IIS) sends it to Drupal.
- Drupal bootstraps and initializes the database, sessions etc.
- Maps the path to a callback function, which gets the primary content.
- Modules can hook into the process and extend functionality and alter the content.
- The Theme System generates the HTML and applies styles it to.
- Drupal returns a fully formed HTML page to the browser.
- The browser renders the HTML page for the user.
Drupal (Now with Varnish!)
- User requests a URL
- Web server (Apache/Nginx/IIS) sends it to Drupal.
- Drupal bootstraps and initializes the database, sessions etc.
- Maps the path to a callback function, which gets the primary content.
- Modules can hook into the process and extend functionality and alter the content.
- The Theme System generates the HTML and applies styles it to.
- Drupal returns a fully formed HTML page to the browser.
- The browser renders the HTML page for the user.
How does Varnish do this?
- A request is recieved
- Varnish determines if it should Lookup, Pass, Pipe or Error.
- Lookup = Request that could be cached
- Pass = Request cannot be cached (cookies) or should not be cached (configuration)
- Pipe = Request should be mainlined to the server (POST or similar transmition of data that should not be interupted)
- Error = Backend is down or varnish is configured to error
- Assuming a Lookup, Varnish sends the request to Drupal.
- Drupal does the long look up and responds.
- Varnish caches a copy of that response.
- This can be from RAM or disk, RAM is highly recommended.
- Request is made for the same thing
- Varnish does a Lookup
- Checks to make sure the cache lifetime has not expired
- Responds with its copy from RAM. (Skipping Drupal entirely)
Installation
(20,000 ft view)
- Download and install Varnish
- (apt-get, yum, make/install)
- Swap Apache off port 80 and put Varnish on
- Adjust your configuration in the .vcl file
- Install the Drupal Varnish module
- (including editing your settings.php file)
- Adjust your Performance settings
Backend Probe
# Define the health check for Drupal Servers.
probe drupal_healthcheck {
.url = "/health_check.php";
.interval = 5s;
.timeout = 1s;
.window = 5;
.threshold = 3;
.expected_response = 200;
}
Backend Definitions
# Define the list of backends (web servers).
# Port 80 Backend Servers
backend web1 {
.host = "192.10.0.1”;
.probe = drupal_healthcheck;
}
backend web2 {
.host = "192.10.0.2”;
.probe = drupal_healthcheck;
}
# Port 443 Backend Servers for SSL
backend web1_ssl {
.host = "192.10.0.1”;
.port = "443”;
.probe = drupal_healthcheck;
}
backend web2_ssl {
.host = "192.10.0.2”;
.port = "443”;
.probe = drupal_healthcheck;
}
Directors
# Define the director that determines how to distribute incoming requests.
director default_director round-robin {
{ .backend = web1; }
{ .backend = web2; }
}
director ssl_director round-robin {
{ .backend = web1_ssl; }
{ .backend = web2_ssl; }
}
Basic Receiver Sub Routine
# Respond to incoming requests.
sub vcl_recv {
# Set the director to cycle between the web servers.
if (server.port == 443) {
set req.backend = ssl_director;
}
else {
set req.backend = default_director;
}
}
Basic Fetch Sub Routine
sub vcl_fetch {
# Don’t allow static files to set cookies.
if (req.url ~ "(?i)\.(png|gif|jpeg|jpg|ico|swf|css|js)(\?[a-z0-9]+)?$") {
unset beresp.http.set-cookie;
}
# Allow items to be stale if needed.
set beresp.grace = 1h;
}
Deliver Sub Routine
# Set a header to track a cache HIT/MISS.
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Varnish-Cache = "HIT";
}
else {
set resp.http.X-Varnish-Cache = "MISS";
}
}
Varnish can’t do everything
Varnish is not great with
- Forms
- Authenticated Users
- Things that really need cookies
But you can do some stuff to help
Checkout ESI (Edge Side Includes)
Metrics
What should you measure?
- Time to First Byte
- Number of requests per second
Metrics
How can you measure it?
- Time to First Byte
- For publically accessible web servers - www.webpagetest.org
- For local development or web servers – Chrome Dev Tools
- Number of Request per second
- Load testing tools – JMeter, BlazeMeter, Siege, Apache Benchmark
How about some Data
- Drupal
- 8130 ms
- ~10 concurrent requests
- Drupal w/ core caching
- 2090 ms
- ~100 concurrent requests
- Drupal w/ Varnish
- 68 ms
- 2000+ concurrent requests
Modules to help with caching and cache clearing
- https://www.drupal.org/project/varnish
- https://www.drupal.org/project/expire
- https://www.drupal.org/project/entitycache
- https://www.drupal.org/project/advagg
- https://www.drupal.org/project/views_cache_bully
- https://www.drupal.org/project/panels_hash_cache
- https://www.drupal.org/project/authcache