During the amazing Umbraco Code Garden 2014 I presented a session titled 'Supercharge your Umbraco'. The session was all about caching with Umbraco and how in today's demanding web environment using these caching techniques can really help scale your application.
The talk covers:
1. Macro Caching
2. Cached Partials
3. MVC Output Caching
4. MVC Donut Caching
5. Varnish
Watch the talk back on the Umbraco stream http://stream.umbraco.org/video/9949630/supercharge-your-umbraco
The example code I used during the presentation is available at the link below, it has all the handlers for purging the donut cache and for managing varnish. https://bitbucket.org/chrisgaskell/umbraco-caches
5. In computing a cache is a component that
transparently stores data so that future
requests for that data can be served faster.
The data that is stored within a cache may be
values that have been computed earlier or
duplicates of original values that are stored
elsewhere.
http://en.wikipedia.org/wiki/Cache_(computing)
13. Macro Caching
The original way to reuse blocks of functionality.
How to:
1. Define macro in back office
2. Add cache policy
3. Call macro from within view
15. Macro Caching
The Good
• Quick and easy to setup with instant results
• No .NET
• Easy to retro fit or fine tune on an existing install
• Cache clears on CMS publish
• Support for querystring parameters so long as they’re passed to the macro as parameters
• @Umbraco.RenderMacro("pageList", new { addSleep = "[@addsleep]"
The Bad
• Difficult to turn off in dev (Macro cache disabler package doesn’t look to be compatible
with 6+)
• With MVC logic is moved into the view as there’s no chance to hijack the route
17. Cached Partials
You don't normally need to cache the output of Partial views but there are
times when this is necessary. Just like with macro caching you can cache the
output of partial views.
This is done simply by using an HtmlHelper extension method:
@Html.CachedPartial("MyPartialName", new MyModel(), 3600)
The above will cache the output of your partial view for one hour (3600
seconds)
http://our.umbraco.org/documentation/Reference/Mvc/partial-views
19. Cached Partials
The Good
• Quick and easy to setup with instant results
• Easy to retro fit or fine tune on an existing MVC codebase
• As the cache duration is passed this could be taken from a configuration setting
and set to easily in dev to 0 secs
• Cache clears on CMS publish
The Bad
• MVC logic is moved into the view as there’s no chance to hijack the route
• If your view data changes the same cached output will be returned.
Please be aware: if you have a different model or view data for any page request,
the result will be the cached result of the first execution
21. Output Caching
Output caching is a full page cache.
Output caching is part of the .NET framework and can be easily used
with MVC or web forms applications.
In MVC output caching is implemented using an action filter attribute
which can be applied to controller actions.
23. Output Caching
The Good
• Available ‘out of the box’ with ASP.NET – there’s nothing to install
• Easy and quick to implement
• Fast and robust
• Easy to share common cache ‘profiles’ across the app from config
The Bad
• Difficult to clear on a publish
• The entire page is cached making personalisation and dynamic content difficult to
manage
• Requires good management in development to ensure developers aren’t seeing
cached content
25. Donut Caching
Donut caching is one form of output caching that is conspicuously absent
from ASP.NET MVC and is greatly missed by many developers.
To implement donut caching the concept is fairly simple:
1. Cache the page output and return it from the cache on subsequent
requests
2. Identify the areas that you do not want to cache (the donut holes). These
areas are marked so that when the page is retrieved from cache these
areas are replaced with non-cached versions before returning the page
28. Donut Caching
The Good
• Gives the huge benefit of having portions of the page render for each
request while the surrounding mark-up comes from cache
• Installs quickly (via nuget is best)
• Easy to add into a well architected MVC solution
• Has a cache manager allowing easy coupling to publishing for purging the
cache
The Bad
• Requires good management in development to ensure developers aren’t
seeing cached content
• Does need some extra code to ensure the cache is purged on publish
35. Varnish Cache is a web application accelerator also known as a caching
reverse HTTP proxy
You install it in front of any server that speaks HTTP and configure it to
cache the contents
Varnish Cache is really, really fast. It typically speeds up delivery with a
factor of 300 - 1000x, depending on your architecture
36. @bsdphk we have a new record on web
infrastructure reduction: From 46 to 5
servers!! @varnishcache rocks!
38. Infrastructure
RAM is what counts to allow the cache to scale. How much RAM
depends on your requirements.
• With varnish you configure the size of the cache
• Varnish also needs memory to do other things, so you'll see a fixed
couple of hundred extra megs.
• Varnish has a overhead of about 1k per object.
• Each thread (e.g., worker) will allocate its own memory, including a
stack. This memory usage will scale and contract as load spawns and
reaps threads.
39. Installation on Ubuntu
To use the varnish-cache.org repository, do the following:
1. curl http://repo.varnish-cache.org/debian/GPG-key.txt | sudo apt-
key add -
2. echo "deb http://repo.varnish-cache.org/ubuntu/ precise varnish-
3.0" | sudo tee -a /etc/apt/sources.list
3. sudo apt-get update
4. sudo apt-get install varnish
40. Installing on Windows?
“Remember that Varnish on Cygwin Windows is not recommended
for productions sites and it is only a proof-of-concept that can be
used to test application on Windows or for checking you VCL while in
that platform.”
https://www.varnish-cache.org/trac/wiki/VarnishOnCygwinWindows
41. Inside Varnish
When a web page or content is requested:
Check if the content is cacheable
If content is in cache
Return cached content
Else
Fetch content from Web server
Put the content in the cache
Return content
Else
Return by fetching from Web server
43. /etc/varnish/default.vcl
backend default {
.host = "umbracocaches.detangled-digital.com";
.port = "80";
}
sub vcl_recv {
set req.http.host = "umbracocaches.detangled-digital.com";
if (req.request == "GET" || req.request == "HEAD") {
return (lookup);
}
}
sub vcl_fetch {
# Remove Expires from backend, it's not long enough
unset beresp.http.expires;
# Set the clients TTL on this object
set beresp.http.cache-control = "max-age=900";
46. Refresh the page and watch the timestamp
jump
http://bit.ly/1ozG165
47. Now have a look at the same page through
Varnish
http://bit.ly/1hjTPCK
48. All well and good, but what happens when I
publish content changes?
49. Cache Invalidation
• purge; removes all variants of an object from cache, freeing up
memory
• ban(); can be used to invalidate objects based on regular expressions,
but does not necessarily free up memory any time soon
50. /etc/varnish/default.vcl
backend default {
.host = "umbracocaches.detangled-digital.com";
.port = "80";
}
sub vcl_recv {
set req.http.host = "umbracocaches.detangled-digital.com";
if (req.request == "PURGE") {
return (lookup);
}
if (req.request == "GET" || req.request == "HEAD") {
return (lookup);
}
}
sub vcl_hit {
if (req.request == "PURGE") {
purge;
56. What Else
• Load Balancing
• Can be configured as round-robin or random
• Probing
• This accesses the heath of the application servers and can take servers in and out of
the balancing pool
• Serving stale cache
• Should the application server go down Varnish can serve a ‘stale’ cache
• A Large set of monitoring and logging commands
• https://www.varnish-cache.org/docs/4.0/reference/index.html
58. Get the sample code
https://bitbucket.org/chrisgaskell/umbraco-caches
See it integrated into a V7 example
https://bitbucket.org/chrisgaskell/gemscafe
Chris Gaskell
@CGaskell
chris@detangled-digital.com
Editor's Notes
Freelance .NET Web Developerchris@detangled-digital.com
Developing with .net since 2001, using ASP3 and VB6 beforehand
Organise the Manchester Umbraco Meetup
Working mostly with digital agencies around Manchester
Complex web applications
Adapting or responding to a wealth of devices
Real time integration
Availability
Content management
People want web pages fast – really fast
Mobile devices are often on slow connections and webpages are becoming increasingly complex, speed is important.
Who in the audience already caches?
Umbraco caches
.NET Caches
Infrastructure caches
Don’t go mental!
Umbraco has many caches over the data layers and request pipeline.
XML Cache
Content types
Document types
Domains
Languages
There are a number of ways we can bolster Umbraco installs by leveraging caches.
Some are from the web, some from Umbraco a number from .NET and the rest by means of infrastructure
Before I get started with fancy caches don’t forget about….
Most will already consider the above
Not to mention how page speed helps with SEO
Let me introduce you to..
Rather than constantly trying to memorise datetime stamps welcome to the supercharger-o-meter
Powered by a HTTP module timing from OnBegingRequest to the end of the request. It shows a percentage of 8seconds and the actual loadtime in ms
[Show the code]
I’m going for zero demo fail, but this is caching!
All the demo code is available on bitbucket, url at the end
The caching demos are Umbraco, MVC and linux based – what could possibly go wrong?
First up macro caching
Partial is a reusable MVC component, it’s like just having the HTML part of a usercontrol.
The HTML helper method is what’s important…
Starting to move away from Umbraco….
Anyone used output caching with Umbraco?
We’re going to take a look att he MVC variant of the output cache.
When the action is executed for the first time, the OutputCacheAttribute intercepts the ActionResult before the output is returned to the client and stores this output for a configurable period of time.
Then on subsequent requests the output is returned from the cache rather than executing the controller action.
Clearing on publish can be difficult. Two options
Set a short duration say 10 seconds
Use the varybycustom and insert a static identifier. Update the identifier on publish.
Moving towards a more customised version of output caching
Available as a nuget package
Built on top of output cachine
This should give you an idea. The donut is static (cached) the whole is new each time.
Or maybe this picture just made you hungry?
Cache manager allows management and clearing of cached items
But what if you want to go even faster?
Cant change the codebase
Concerned with cache overhead on your application server
You’re proxying content from other sites
You have embedded feeds
You need some extra redundancy
You don’t want to load balance…
But what if you want to go even faster?
Here’s a typical web request, there’s no varnish here and lets imagine the developer hasn’t implemented any output type caches.
My wife’s called Gem and she likes dresses:
So Gem askes a website for some dresses
The webserver asks the database for some dresses
The database finds some dresses and gives them to the webserver
The webserver creates some HTML based on the data
The HTML goes back to Gem
Here we’ve added varnish
Gem also likes hats:
So she askes a website for some hats
She hits varnish, but no one has ever asked for hats
So varnish asks the webserver
The webserver asks the database for hats
The database finds some hats and gives them to the webserver
The webserver creates some HTML based on the data
The HTML goes back to varnish which will store it for the next request
Varnish passed the HTML to Gem, who was a little tired of waiting.
An hour later Gem has found my credit card and wants the hat
So she askes a website for the same hats
She hits varnish
Varnish realises it’s already been asked for this
So Varnish passes the HTML to Gem, who’s amazed with the speed
The others servers haven’t done anything and are happily having a rest
A real world implementations here
46 to 5 servers!
And how much does this all cost….
Varnish is free software licensed under a two-clause BSD licence, also known as the FreeBSD licence.
RAM is what really counts for bigger sites
Gigabit networking. Varnish can easily saturate 100mb networks
Typical installation on a Ubuntu server
Varnish can be executed on Windows using Cygwin DLL.
It’s not for production, but handy for testing and developing.
Here’s a brief overview of a request going through varnish
We can add code to each of the ‘methods’ shown in the path. The extra configuration code we add to the file is executed before the
The VCL language is a small domain-specific language designed to be used to describe request handling and document caching policies for Varnish Cache.
The basic syntax of VCL is reasonably straight forward. It is inspired mainly by C and Perl
The functions of VCL are not true functions in the sense that they accept variables and return values. To send data inside of VCL, you will have to hide it inside of HTTP headers
Your VCL code is executed before the standard Varnish VCL. So you are simply adding to the built in configuration rather than starting from scratch
So you can get up and running easily with the base configuration
DEMO – Stop the site on the amazon VPS
Demo publish event
Purge and ban are the two cache clearing options
Call Varnish with the ‘PURGE’ verb by convention
Show how purge is handled
Purge is not implemented out of the box
To purge a URL the convention is to call Varnish with the PURGE verb.
We can then hook this up onto the CMS publish event.
You may want to do this differently, say by calling PURGE from a scheduled task or similar – depends on your solution
Of course for a ‘real’ application things are a little more complex.
There are things to think about such as cookies and security on purges