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]

Reply via email to