If every single dynamic page of your site requires knowledge of the session, and must hit the backend, then you're kind of stuck. But there are lots of ways to design around that.
For example... Edge Side Includes, supported by Varnish, let you do front-end caching of page fragments, stitched together by the proxy rather than the web application. This can give you a huge boost (to performance and scale), even if you have to hit the web application for some part of the page.
Keep in mind, once you start adding front-end caching to your application, you need to think of your cache as part of your app. :-)
You might want to take a look at the Turpentine module for Magento, which tightly integrates Varnish with Magento. It's a good example of retrofitting front-end caching, cookie generation, and ESI fragment caching into an existing e-commerce application.
If a specific page item can be cached is really up to if the backend application takes cookie state into account when the page item is made.
The Varnish default of not caching anything when cookies are present is because we have no idea if the backend writes "Welcome back, krat0sprakhar!" when it sees the username in an incoming cookie. Sending that item to every user would be unfortunate.
Other than that, I'd recommend you evaluate your needs and not just pick a technology. If your page response times are low enough already, and your backends/appservers scale to as many concurrent buyers you think you need, you're good without Varnish/caching.
If you want to know more about it, there is a funny thread about it https://www.varnish-cache.org/lists/pipermail/varnish-misc/2...
if(req.http.Cookie) {
# ignore front-end cookies (prefixed with "ui-")
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(ui-[a-z-]+)=[^;]*", "");
# ignore google cookies
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js)=[^;]*", "");
# Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
# Remove empty cookies.
if (req.http.Cookie ~ "^\s*$") {
unset req.http.Cookie;
}
}
In my read-mostly use-case, this allows ~90% of site traffic to be served by varnish, even though the site is totally dynamic (for not-logged-in users, all the state that we care about is in the GET parameters).Another way of doing it is to exclude all cookies, and only care about session-cookies.
You can cache while using cookies. If you use a cookie to change the page in any way add Cookie to you Vary headers. In Varnish I don't cache response with Vary ~ "Cookie". I also don't cache any response that sets a cookie.
Now if you have a backend that does modify the page using what is in a cookie but doesn't set the Vary header, then using Varnish can be quite a pain. This is hardly Varnish's fault that the backend is crappy.
If you've worked with Magento then you know it relies heavily on cookies and sessions. Even with all difficulties of modifying Magento I was able configure Magento and Varnish to work together perfectly within a week.
I can point you to the Magento site running with Varnish if you send me an email.
So it's useful if some amount of your content is always the same, with other parts being requested per request (or cached depending on cookies, or whatever else).
Varnish has proven to be very hard to use with nginx in the above setup. Especially, trying to understand the ssl bit is getting to be really hard.
Can it also work with spdy?
Just get your /admin-system to send the correct Cache-Control headers, Varnish will respect the headers, and serve it correctly.
b) You have to terminate SSL connections before hitting Varnish. There is very little chance SSL termination will ever be part of Varnish. On AWS you can terminate with ELB.
c) Varnish can add HTTP headers and it will respect the headers your backend sets.
d) Varnish can disable caching for a specific path or again it will respect the No-Cache headers a backend sets.
Or is it nginx (SSL termination) -> varnish -> nginx (server) -> Rails
It is not as bad it seems since using Nginx to terminate SSL and forward is just a really simple config file. If you have a lot of cached resources then the path is mostly Nginx -> Varnish. Varnish is probably over 100 times faster than Rails at serving anything cacheable.
if (req.http.host == "www.foo.net") {
set req.http.host = "foo.net";
}Do you know of any good starting config file that can be used ?
* https://github.com/mattiasgeniar/varnish-3.0-configuration-t... (fairly well maintained with CMS specific VCL examples)
* https://github.com/slashsBin/nuCache (library for different programming languages, not so CMS centric)
Both of these are listed in our utilities directory:
* https://www.varnish-cache.org/utilities
Other Varnish (VCL) extensions can be found in the VMOD directory:
* https://www.varnish-cache.org/vmods
If you have ideas on how to make both these resource more visible and accessible for our users, please let me know.
I think it would be great if varnish had an official repo with different configuration templates for different stacks that could be used as "drop-in".
For example, my question about a fairly basic Rails config (https://news.ycombinator.com/item?id=8431927) had a couple of different answers disagreeing about stuff.
Also, things like SSL termination are something that the documentation skips over entirely - I understand completely that Varnish does not implement it, but Varnish necessitates the introduction of certain other players in the stack, which it should document.
For example, a canonical example of varnish setup as Nginx (SSL termination) -> Varnish -> Nginx (reverse proxy) -> App would be very useful.
hit me on twitter @kentonjacobsen
Can you give more details about the hardware setup?
hit me on twitter @kentonjacobsen
We ended up writing our own system, with our own high-concurrent LRU cache, that was more tightly coupled with our application servers (and thus able to figure out what the cache key should be). It ended up being trivial to then add things like ESI, purging, grace and saint mode.
Point being, since then, I've had a hard time seeing where Varnish fits between proxy_cache for simple url+query caching, and rolling your own.
Varnish gives you enough configurability to do just about anything, but the end result will be a spaghetti mess of VCL, inline C and possibly custom varnish modules. The more sustainable route is to build your own caching front end, however I think it's a bit unrealistic to assume that all startups have the engineering talent (or time) in-house to implement that sort of thing.
Your own caching will make your webapp (or API) scale (say 2x faster or serve 15x the amount of users), but if you need your app to take some serious beating (say 100x to 400x the amount of users with minimal ttfb) because your site/app suddenly becomes flavour of the month on the Internet, then you will really need Varnish.
After seeing several Paywall and API deployments and all sorts of other advanced business logic, such as GeoIP detection or Mobile device classification, applied in the cache layer while keeping a sane and simple VCL, I am not sure your initial point is the case. The normal way to write VCL is to keep it simple.
(Yes, I am biased, but my point is still valid).
When we moved away from Varnish towards our own integrate cache, our hit ratio went from 50% to 80% on average, and some individual routes hit over 95% (we proactively purged+refetched in the background through a queue).
So maybe you're right, but for the opposite reason that you state. Our scale and performance requirements were so great, a custom solution made more sense.
Obviously, depending on what you were trying to do and to which extend Varnish was extendable then (VMODs were added in 3.0) it might not have been the best option there is.
Anyway, thank you for your reply. It was a very interesting insight you came with there.
The major bug it had was that it would work normally for hours, but then it would randomly let the flood of requests through basically killing our servers. It happened over and over and over again. We had multiple talented sysadmins look at it, and none of them could give us any explanation. The only solution was to restart it, and warm the cache all over again. We couldn't figure out what sets it off, it looked just so random.
Response headers is the first thing we checked, there are only a few of them that affect Varnish:
[Varnish Software sales hat on]
If anyone from Varnish AS is reading this (OP?), please consider having a Varnish Summit on the east coast of the US sometime.
Soon.
Please.
Varnish will very likely be an order of magnitude or two faster than sending requests to your app. You can get going with a simple config in a few minutes and without breaking anything (just have varnish listen on a different port and use :80 or your app server as the back-end), so I'd strongly suggest playing with it if you're curious. It's pretty impressively fast software, and VCL gives you an awesome abstraction for controlling how the cache handles different routes.
I'm still running 3.x because they broke a bunch of stuff. I discovered this when I updated a couple of dev boxes and varnish stopped working.
* Upgrading notes: https://www.varnish-cache.org/docs/4.0/whats-new/upgrading.h...
* A script by Fed that will do 70-90% of the job for you: https://github.com/fgsch/varnish3to4
Let us know how it went :-)
And, frankly, I think the machines _are_ happy to make the announcement.