Lambda the Ultimate

inactiveTopic Apache vs. Yaws
started 2/12/2003; 7:23:36 AM - last post 2/17/2003; 9:53:26 PM
Noel Welsh - Apache vs. Yaws  blueArrow
2/12/2003; 7:23:36 AM (reads: 3426, responses: 19)
Apache vs. Yaws

Apache is the web-server most of the world uses. Yaws is a web-server written in Erlang. Apache has recently been totally redesigned to take advantage of OS threads in an effort to support higher loads. How successful have the Apache team been? Not very, compared to Yaws. In a through-put benchmark Apache falters at around 8'000 concurrent sessions. Yaws handles over 80'000 concurrent sessions. Why the difference? Because Erlang doesn't use OS threads, but its own user-level threads. In other words, continuations. The two points I got from this are:

  • Theory is inextricably tied up with practice
  • Languages are operating systems

The talk from LL2 is also worth a read.

Seen on the plt-scheme mailing list. Thanks Brent!


Posted to implementation by Noel Welsh on 2/12/03; 7:26:20 AM

Ehud Lamm - Re: Apache vs. Yaws  blueArrow
2/12/2003; 10:02:24 AM (reads: 2282, responses: 0)
Languages like Erlang highlight the difference between languages that support concurrency (e.g., Java, Ada etc.) and languages that actually encourage concurrency.

Johannes Grødem - Re: Apache vs. Yaws  blueArrow
2/12/2003; 10:33:26 AM (reads: 2273, responses: 0)
Hi, I'm curious about one thing. If there are any Erlangers here, do you think it would be hard to implement something like Erlangs model of concurrency on top of, say, Common Lisp?

Patrick Logan - Re: Apache vs. Yaws  blueArrow
2/12/2003; 11:37:06 AM (reads: 2231, responses: 1)
An implementation of Erlang exists in Gambit Scheme. This implementation has the same results.

In general, multiplexing many user processes per OS thread is a common technique. If the new Apache implementation is 1:1 with OS threads, that would be an unfortunate choice.

Ehud Lamm - Re: Apache vs. Yaws  blueArrow
2/12/2003; 12:02:10 PM (reads: 2273, responses: 0)
Also see this interesting message from the same mailing list thread, about erlang and concurrency abstraction.

John Eikenberry - Re: Apache vs. Yaws  blueArrow
2/12/2003; 1:37:47 PM (reads: 2191, responses: 1)
As the author indicated, this is not necessarily an issue with using OS level threads but more of an issue of the platform/OS and its implementation of threads. I'd like to see the same test run using NPTL [1]. Which, BTW, seems to demonstrate that 1:1 threading is not such a bad choice after all.

[1] http://www.kerneltrap.org/node.php?id=422

Ken Meltsner - Re: Apache vs. Yaws  blueArrow
2/12/2003; 1:53:30 PM (reads: 2163, responses: 0)
There's a "threadless" Java server implementation that beat Apache -- check out Matt Welch's SEDA project.

Also, Apache no longer has one request, one process. The server's system-dependent portion maps Apache request handlers to system threads/processes. This was the biggest change from Apache 1.x to Apache 2.x.

Ehud Lamm - Re: Apache vs. Yaws  blueArrow
2/12/2003; 1:53:31 PM (reads: 2216, responses: 0)
The implementation technique is, of course, fundamental. However, it is important to note the the erlang language designers wanted to support massive concurrency from the get go.

Brent Fulgham - Re: Apache vs. Yaws  blueArrow
2/12/2003; 3:29:46 PM (reads: 2146, responses: 0)
Please note that the Yaws comparison was done against Apache 2.x series, which changed from the request/process to a request/thread model (which was supposed to be a big performance win.)

Also, it might be interesting to read this thread on the PLT mailing list. MzScheme's concurrency is also quite good, and it would be interesting to run a comparison of Yaws versus the PLT web server for concurrency issues.

Patrick Logan - Re: Apache vs. Yaws  blueArrow
2/12/2003; 3:53:11 PM (reads: 2135, responses: 0)
Apache 2.x series, which changed from the request/process to a request/thread model (which was supposed to be a big performance win.)

Seems the Apache folks did not read the literature. When they redesigned, they should have virtualized the request architecture.

These techniques have been documented for years. If you make your code virtual, then you can map them 1:1 or N:1 as desired.

Hopefully their rewrite is not so poor that they'd have to rip up too much to get to this architecture. You never know about software developers.

Patrick Logan - Re: Apache vs. Yaws  blueArrow
2/12/2003; 3:59:18 PM (reads: 2139, responses: 0)
NPTL... seems to demonstrate that 1:1 threading is not such a bad choice after all.

If you know your code will always run on a reasonable OS implementation of threads.

What it probably demonstrates is you should design a virtual thread interface that can be mapped 1:1 or N:1 depending on the quality of the OS implementation.

Patrick Logan - Re: Apache vs. Yaws  blueArrow
2/12/2003; 4:19:13 PM (reads: 2133, responses: 0)
From the NPTL discussion list...

Linus Torvalds: 100k threads at once is crazy

The OS guys are still living in their own little world that's dated about 1982 and written in C.

John Eikenberry - Re: Apache vs. Yaws  blueArrow
2/12/2003; 5:20:50 PM (reads: 2112, responses: 0)
> Linus Torvalds: 100k threads at once is crazy

Using Posix style threads, I'd have to agree. Posix threads were just not designed with this level of usage in mind. Which is why concurrent lanugages like Erlang and Mozart/Oz don't use Posix threads.

Patrick Logan - Re: Apache vs. Yaws  blueArrow
2/12/2003; 5:45:42 PM (reads: 2118, responses: 0)
Posix threads were just not designed with this level of usage in mind. Which is why concurrent lanugages like Erlang and Mozart/Oz don't use Posix threads.

Exactly. If the OS developers were paying attention to the kinds of applications being built these days, they might avoid or at least augment these "old-style" threads.

Now back to reality... legacy code, backward compatibility, familiarity, etc.

I'm just sayin'...

Ken Hirsch - Re: Apache vs. Yaws  blueArrow
2/13/2003; 2:27:21 PM (reads: 1923, responses: 0)
Other than avoiding the particular type of DOS attack that was modeled, I'm not sure of the relevance of this. Yes, Erlang can support a huge number of threads that do nothing but process one character every ten seconds, but how does it stack up for anything else? It would be helpful to have some numbers about throughput and response times for various mixtures of transactions: large/small output and CPU-bound v. IO-bound.

Also, I'm assuming that you have to stay in Erlang for this to work. Is there any multilanguage programming?

Isaac Gouy - Re: Apache vs. Yaws  blueArrow
2/13/2003; 3:04:03 PM (reads: 1911, responses: 0)
Until Luke Gorrie stands in for Claes Wikstrom, questions of detail might need the expertise of the YAWS list.

Luke Gorrie - Re: Apache vs. Yaws  blueArrow
2/14/2003; 8:03:22 AM (reads: 1829, responses: 0)
I don't know the details of the benchmark, but 80,000 concurrent connections sounds a bit incredible -- that's a heck of a lot of file descriptors :-). But I know not.

Network programming in Erlang is very nice though. You get a convenient high-level interface, much more like Unix processes than threads, and under the hood it's all done efficiently in a single Unix process with select()-style I/O, the same way people write scalable C servers.

By the way, at Nortel we're now shipping Yaws as a major piece of our brand new SSL-based VPN product: http://www.nortelnetworks.com/products/01/alteon/sslvpn/doclib.html

Luke Gorrie - Re: Apache vs. Yaws  blueArrow
2/14/2003; 8:17:40 AM (reads: 1823, responses: 0)
Regarding implementing Erlang-like extensions in Common Lisp, I think the hard part is capturing the continuation of a process to schedule it in and out. As Patrick points out, you don't have this problem in Scheme. Also, Erlang-like process abstractions built on Common Lisp seem likely to be half-baked, since while you might support the programming style, I don't think you could enforce the process separation properly in the presence of all those destructive operations. But then, I'm not a real Common Lisp hacker.

I have tried to do this very thing in Emacs Lisp though, and it turned out very well, though half-baked in the same sense. I presented a paper about it at the last Erlang conference, and it's been featured on LtU.

Vlad S. - Re: Apache vs. Yaws  blueArrow
2/17/2003; 9:53:26 PM (reads: 1677, responses: 0)
Well, Dick Gabriel and McCarthy worked on implementing medium-grained threads on top of Common Lisp in the 80s. The project was called Qlisp. The basic unit of concurrency was a special-case lambda form, and the whole concept of futures was very well treated. With Common Lisp, the big problem when it comes to concurrency seems to be dynamic binding of variables.

Right now, CMUCL and SBCL both have coarse-grained cooperative threading in the form of the Serve-Event facility, but it's not very fast and I don't think it can scale well. My PIII-500 running Paserve on CMUCL can push a max of about 19-20 simultaneous requests for a completely dynamic (albeit fairly simple) 80k page.

Of course this setup can easily be (as I found out just last week) DOSed by clients just waiting on open connections. I think I'll do what Dan Barlow does with his Araneida CL web server (it powers Cliki), and run it behind an Apache 1.3 proxy, which seems to handle abuse very well.

Besides not having continuations (from some of the Scheme papers from the proceedings from the 1989 US/Japan workshop on parallel Lisp I got the impression that they had questionable value when it came to actual parallel machine implementations), I don't see why Common Lisp isn't a good platform for implementing lightweight threads. From my limited knowledge of Erlang, I suppose such a system can be made with closures, and as long as you keep away from dynamically bound variables the performance might be ok. Most current work (including the abovementioned Daniel Barlow's exciting new addition of native threads to SBCL) on Common Lisps tends towards rather coarse-grained threads, for supporting things such as CLIM and various network servers.