the potential to… eliminate some interactions, improving efficiency, scalability, and user-perceived performance by reducing the average latency of a series of interactions.”
Norway's most popular newspapers • Suffered the same problems of all digital media platforms • Poul Henning Kamp, a BSD core developer, was the lead developer and application architect for Verdens Gang • As a kernel developer, Kamp has a particular set of skills that allowed him to approach this problem from a new angle
line of demarcation between primary and secondary storage • In short, primary storage (RAM in modern computers) can be accessed directly by the CPU • Secondary storage is accessed via an I/O channel or controller
scientists were experimenting with virtual memory. • By the 1970s, virtual memory was common in commercial computers • Virtual memory is an abstraction that allows secondary storage to extend primary storage • The operating system cooperates with specialized hardware to manage the paging of data in and out of virtual memory.
0.3 ns 1 m (1 step) 1 second L1 Cache 0.9 ns 3 m (3 steps) 3 seconds Main Memory 120 ns 360 m (to the highway) 6 minutes SSD 50 µs 170 km (Richmond, VA) 2 days HDD 5 ms 13,000 km (Hong Kong) 5 months
is a cache • The operating system swaps data between high-speed primary storage and slower secondary storage based on factors like age and access frequency • Commonly accessed data is kept “hot” and ready while rarely-needed data can be quickly retrieved when called for
memory space • Workspace contains pointers to cached objects, headers, etc • Varnish prioritizes worker threads by most recently used • These factors combine to reduce overall disk & memory ops
root and starts the child (which does all the work) • manager monitors child and restarts it if it fails • manager interacts with the varnish cli interface (varnishadm) • child runs with more limited permissions and handles traffic
Varnish. Clears all cache • service varnish reload — Reloads the currently active VCL • varnishadm vcl.load <name> <filename> — Loads a VCL • varnishadm vcl.use <name> — Makes VCL named <name> active • varnishadm param.set <param> <value> — Sets parameters
if the request has a Cookie header or if the response has a Set-Cookie header • NB: It is better to not cache content, or to cache multiple copies, than to deliver content to the wrong person.
going between Varnish and the backend servers. This will be useful when we want to optimize cache hit rates. • -c — Same as '-b' but for client side traffic. • -m tag:<regex> — Only list transactions where the tag matches a regular expression. If it matches you will get the whole transaction.
7231, 7232, 7233, 7234, & 7235) • Requests consist of a method, headers, and sometimes a body • Methods — GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE, or CONNECT • Responses consist of a status, headers, and sometimes a body • Many requests can be sent over a single connection
which a resource is considered stale • Last-Modified — Date & time when the resource was updated • Etag — “Entity tag,” a unique value for a resource’s contents. Usually a hash • Age — Number of seconds a resource has been in cache
if the resource’s last modified date/time is more recent than the date/time specified • If-None-Match — If the resource’s Etag differs from the Etag specified, server should sent a fresh resource
— Any cache may cache the content • no-store — No cache should store the content • no-cache — Store the content, but don’t serve it without validating it • max-age — Number of seconds a cache may store content for • s-maxage — Same as max-age, but applies to public caches only • must-revalidate — Stale content cannot be served without validating it
requests in isolation • return(action) exits one state and moves to the next • Default VCL is present beneath your code and is appended during compilation
Subroutines — sub [name] { … } • Loops — Nope! • Termination — return() • Objects — Struct-like objects that map a name to a group of client addresses acl local { "localhost"; // myself "192.0.2.0"/24; // and everyone on the local network ! "192.0.2.23"; // except for the dialin router }
match of <regex> in <str> with <sub> • regsuball(<str>, <regex>, <sub>) — Replace all matches of <regex> in <str> with <sub> • ban(<regex>) — Invalidate all cached objects that match <regex> • call(<subroutine>) — Call a subroutine • hash_data(<input>) — Adds data to the hash input. By default, Host and URL of the request are used • new() — Creates a new object • rollback() — Restore request headers • synthetic(<string>) — Prepares a synthetic response • return(<action>) — Terminate a subroutine
cache, send request to the backend and return the response • pipe (→vcl_pipe) — Switch to a proxy-like mode • hash (→vcl_hash) — Attempt a cache lookup, possibly entering new data in the cache • synth — Generate a synthetic error response and abandons the request • purge (→vcl_hash→vcl_purge) — Purge the object and any variants
we attempt to fetch • req.hash_always_miss — (bool) Force a cache miss for this request. If set to true Varnish will disregard any existing objects and always (re)fetch from the backend • req.http.[header] — The corresponding HTTP header • req.method — The request type (e.g. "GET", "HEAD") • req.restarts — Count of how many times this request has been restarted • req.url — The requested URL • req.xid — Unique ID of this request
from a backend • deliver (→vcl_deliver) — Deliver the response, possibly caching it • abandon — Abandons the request and returns an error • retry — Retries the backend request. When the number of retries exceeds max_retries, Varnish will return an error.
this response was fetched from • beresp.backend.name — Name of the backend this response was fetched from • beresp.grace — Set to a period to enable grace • beresp.http.[HEADER] — The corresponding HTTP header • beresp.proto — The HTTP protocol version used the backend replied with • beresp.reason — The HTTP status message returned by the server • beresp.status — The HTTP status code returned by the server • beresp.storage_hint — Hint to Varnish that you want to save this object to a particular storage backend • beresp.ttl — The object's remaining time to live, in seconds. beresp.ttl is writable • beresp.uncacheable — (bool) Marks the response as uncacheable
deliver(→vcl_deliver) — Deliver the object. Control passes to vcl_deliver • synth(status code, reason) — Return the specified status code to the client and abandon the request. • restart — Restart the transaction
pure unadultered hit, deliver it return (deliver); } if (obj.ttl + obj.grace > 0s) { // Object is in grace, deliver it // Automatically triggers a background fetch return (deliver); } // fetch & deliver once we get the result return (fetch); }
document was not found in the cache • synth(status code, reason) — Return the specified status code to the client and abandon the request • pass (→vcl_pass) — Switch to pass mode • fetch (→vcl_backend_fetch) — Retrieve the requested object from the backend • restart — Restart the transaction sub vcl_miss { return (fetch); }
the request is passed on to the backend, and the backend's response is passed on to the client, but is not entered into the cache • synth(status code, reason — Return the specified status code to the client and abandon the request • pass — Proceed with pass mode • restart — Restart the transaction
Varnish not to return cached objects that meet certain criteria • Bans are checked when a cache hit is made • Bans can be set from CLI or with custom VCL • varnishadm ban req.req.url ~ “\.png$” bans all *.png files • Banned content remains in cache, memory is not freed
Varnish serve them even when they are stale, under certain circumstances • When “graced” content is served, Varnish automatically attempts to refresh it
state engine from the top, with any changes to the request saved • Varnish can make intelligent decisions about whether or not to serve questionable content
composition • Allows the combination of cached and uncached resources in to a single whole • Varnish implements a small subset, esi:include and esi:remove
— Returns TRUE is a backend is healthy • strstr(stringA, stringB) — Returns the substring if the second string is a substring of the first string • man vmod_std
included in VCL is compiled with the VCL and dynamically linked to Varnish in memory. • Embedded C essentially becomes part of the Varnish process • If your code produces a segfault, Varnish will crash • Holy crap, don’t do this, why are you still reading this?