4. What?
=
Reverse‐Proxy
... à la HAProxy, Pound, mod_proxy_balancer etc.
+ Cache
... only proxy to backend if necessary
a.k.a.: „HTTP Accelerator“ (= BS Bingo)
Other „HTTP Accelerators“: Web Cache 10g
BIG‐IP
6. Architecture: Cache Store
Squid Varnish
Mem‐Store Disk‐Store VMM (OS)
VMM (OS) RAM HDD
RAM HDD
• one file per object (pre 2.7) • one big file mapped to VM
• book keeping (disk vs. memory)
• VMM often „smarter“
http://varnish.projects.linpro.no/wiki/ArchitectNotes
7. Architecture: VCL
Varnish Configuration Language
DSL, compiled to C code (srsly!)
allows inline C code
C{
syslog(LOG_INFO, “Just served the 1000000th page. Hooray!");
}C
hooks into a requests lifecycle
Backends, ACLs, LB‐strategies defined here
can be hot‐loaded into a running varnishd
hot‐switching between multiple versions/profiles
9. Installation
Debian/Ubuntu: apt-get –t unstable install varnish
OS X via MacPorts: sudo port install varnish
From source: ./configure && make && make install
Interesting files:
/etc/default/varnish
/etc/varnish/*.vcl
10. Configuration
Zero configuration in a perfect world
(= all origin servers perfect HTTP citizens, setting correct
cache control headers, conservative use of cookies)
Varnish won't cache anything "private" or carrying a
cookie by default
The real world sucks:
Tracking cookies (Google Analytics)
Session cookies although no data in session
"Cache‐control: private" by default (Rails) *
...
(* which is a sensible default, btw.)
14. VCL: Hooks
Most important:
vcl_recv Request comes in, decide what to do
vcl_fetch Fetched obj from backend, allows tweaking
vcl_deliver Object is about to be delivered to client
vcl_hash Calculate hash key for lookup, defaults to full URL
Other hooks:
vcl_miss, vcl_hit, vcl_error, vcl_discard,
vcl_timeout, vcl_pipe, vcl_pass
http://varnish.projects.linpro.no/wiki/VCL
15. VCL: Functions & Variables
regsub(), regsuball(), purge_hash(), purge_url()
own subroutines (not functions) with sub foo { ... }
include "other.vcl"; to split files into parts
req.* Request
resp.* Response
bereq.* Backend Request
obj.* requested Object
client.*, server.*
set / unset for variables, remove additionally for headers
http://varnish.projects.linpro.no/wiki/VCL
16. Example: Choose backend
sub vcl_recv {
if (req.host ~ "slowapp.com$") {
set req.backend = slow_j2ee_app;
} else {
set req.backend = other_backend;
}
}
17. Example: Serve static assets
sub vcl_recv {
if (req.url ~ "^/(images|javascripts|styles)/") {
remove req.http.cookie;
}
}
sub vcl_fetch {
if (req.url ~ "^/(images|javascripts|styles)/") {
remove obj.http.set-cookie;
}
}
18. Example: Remove certain cookies
sub vcl_recv {
set req.http.cookie = regsuball(
req.http.cookie,
"__utm[azc]=[^;]+(; )?", ""
);
set req.http.cookie = regsub(req.http.cookie,
"; $", "");
if (req.http.cookie ~ "^ *$") {
remove req.http.cookie;
}
}
19. Example: "Stale while revalidate"
Serve slightly stale content while a fresh version is fetched
=> better user experience + no thread pileup
sub vcl_recv {
set req.grace = 2m;
}
sub vcl_fetch {
set obj.grace = 2m;
}
http://www.rfc‐editor.org/internet‐drafts/draft‐nottingham‐http‐stale‐controls‐00.txt
23. More Tools:
varnishlog: Generate (customized) logs
varnishncsa: Generate Apache compatible logs
varnishadm: Manipulate a running varnishd
varnishadm
-T localhost:6082 purge.url "^/images/"
varnishadm –T localhost:6082 vcl.load /etc/my.vcl
varnishreplay: Parses a log generated by varnishlog
and replays the traffic!
24. Varnish & Rails
Proper use of expires_in instead of page caching
Only use session if really necessary
Purging of content possible with:
`varnishadm –T #{hostport} purge.url #{url2purge}`
net/telnet
klarlack: http://github.com/schoefmax/klarlack
!secure the connection to varnish's admin interface!
(ssh tunnel, iptables etc.)
25. Varnish & Rails: Sweepers
# environment.rb
config.gem "schoefmax-klarlack", :lib => 'klarlack', :source => 'http://gems.github.com'
VARNISH = Varnish::Client.new('1.2.3.4:6082')
# app/sweepers/blog_sweeper.rb
class BlogSweeper < ActionController::Caching::Sweeper
observe Post
include ActionController::UrlWriter
after_save(post)
expire_post(post)
end
after_destroy(post)
expire_post(post)
end
private
def expire_post(post)
VARNISH.purge :url, post_path(post)
VARNISH.purge :url, latest_posts_path
end
end
26. Misc: Edge Side Includes (ESI)
Invented by Akamai & Co.
<esi:include src="http://example.com/friend_feed"/>
http://www.w3.org/TR/esi‐lang
fragment_fu‐plugin for Rails (part of mongrel‐esi)
Header, TTL: 15 min
Activity‐
Nav,
Article, Feed,
TTL:
TTL: 5 min TTL:
60 min
2 min