On Sat, 23 Mar 2002, Andreas J. Koenig wrote:
> >>>>> On Sat, 23 Mar 2002 10:03:54 -0500, Barrie Slaymaker <[EMAIL PROTECTED]> >said: > > > nod. On the other hand, I think that for the scales of load you're > > talking about, mod_perl should not even be invoked and a font end > > "reverse" or "invisible" caching server should probably be used. Even > > with AxKit's more efficient-than-mod_perl start up implementation, > > getting in and out of the perl interpreter is not as fast as we would > > all like it to be. > > Eeek, I wasn't aware of that! You make me even more curious. I, for one, definitely agree with the original message: caching, at least at the whole-page level and for very busy sites, really requires something in front of Apache. I'd actually take the reasons for this a bit further than Barrie, though. It is bad that AxKit has various layers of code to pass through in its cache lookups, but I think it's actually even worse that Apache uses a multi-process model and each mod_perl process is typically about 15MB in the real world, in my experience. Think about it: even if the processes are consistently 15MB and no more (which you can't rely on), you can probably only get a max of about 25 Apache processes active on a web server. Apache uses one process per active connection, and individual Apache processes will be kept busy during client download time. So, as a result, those users connecting to the system with 14.4kbit modems that are downloading your cached 30kb home page will keep an Apache process (one of only 25 per server!) busy for 17 seconds! Even if all of your pages are cached, you're going to hit a bottleneck of some kind, possibly a *memory* bottleneck, unless you buy a lot of hardware. In this particular example, if everybody only hits your home page, with a 100% cache hit rate, but they all use a 14.4 modem, your capacity per server is just 25/17=1.47 pages per second (plus a further reduction due to AxKit/Apache CPU overhead). Any busy site can't afford to be kept hostage by slow modem users. The solution is simple: stick squid in front of Apache, running in http-accel mode. Squid, as an http-accel proxy, will act as a buffer for those outgoing pages, and it will also cache pages very well. Squid itself is also implemented as a single thread/single process daemon that uses nonblock I/O to handle a huge number of simultaneous connections (in the thousands) while completely avoiding the overhead of context switches and multiple processes. When a connection comes into squid while it's running in http-accelerator mode, if it's a cache-miss, squid will immediately open a backend connection to your Apache server (or one of them, anyway) and request the page. As soon as it starts receiving data from the web server, it passes it off to the frontend. But if the frontend connection can't keep up cuz the user's connected via two cans and a piece of string, squid will continue to accept data from the backend into its per-connection buffer (which is maybe 20-30K or something, I don't remember). When the Apache's done, squid says "thanks" and closes the request (which, btw, is *always* keep-alive at the backend). The user could take an *hour* to download a page, but we don't care because the Apache process is freed up and Squid's capacity is only reduced by maybe 1/1000th. And then, of course, you have the obvious effects of possibly having a 95% cache hit rate on squid itself. My experience is that if your site is fully dynamic and pages can't be cached, you might reduce the number of web servers needed by 20-30% just by sticking a squid server in front. If your site is cacheable but implements the pages as statically-generated pages (which AxKit can't currently do), you might drop the number of servers needed by 40%. Dynamic servers that hold cacheable content that isn't cached could obviously be reduced by 90%. Hmm...this is kinda long, I know, but this kind of thing is hard to explain quickly while holding on to the detail. As a side note, what I'm realizing lately is that I could do some amazing things with pages that are composed of different blocks that have different caching attributes on them (the feature products have a cache TTL of 2 hours, for example, but the per-user shopping cart information in the sidebar has a TTL of 15 seconds). Full-page caching is pretty fast, after all, but it's really inflexible. Squid can only do full-page caching. The interesting thing about that realization is that AxKit also only does full-page caching. It doesn't even support dynamic content retrieved from subrequests, at least pre-1.5. It also doesn't view "load-from-cache" and "save-into-cache" as just another step in the pipeline, which perhaps it should. As a result, I tend to think that really for anybody, AxKit's caching is just not terribly useful, for busy or not-busy sites, and for static xml or dynamic xsp. Anybody could simply stick Squid in front and actually get a better result. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
