📄 00000006.htm
字号:
<HTML><HEAD> <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER>发信人: cybergene (活泼的基因), 信区: Linux <BR>标 题: The C10K problem <BR>发信站: BBS 水木清华站 (Mon Dec 13 14:03:09 1999) <BR> <BR> <BR>The C10K problem <BR> <BR>It's time for web servers to handle ten thousand clients simultaneously, <BR> don't you think? After all, the web is a big place now. <BR> <BR>And computers are big, too. You can buy a 500MHz machine with 1 gigabyte <BR> of RAM and six 100Mbit/sec Ethernet card for <BR>$3000 or so. Let's see - at 10000 clients, that's 50KHz, 100Kbytes, <BR>and 60Kbits/sec per client. It shouldn't take any more <BR>horsepower than that to take four kilobytes from the disk and send <BR>them to the network once a second for each of ten thousand <BR>clients. (That works out to $0.30 per client, by the way. Those <BR>$100/client licensing fees some operating systems charge are <BR>starting to look a little heavy!) So hardware is no longer the <BR>bottleneck. <BR> <BR>One of the busiest ftp sites, cdrom.com, actually can handle 10000 <BR>clients simultaneously through a Gigabit Ethernet pipe to its <BR>ISP. ( Here's a somewhat dated page about their configuration.) Pipes <BR>this fast aren't common yet, but technology is improving <BR>rapidly. <BR> <BR>There's interest in benchmarking this kind of configuration; see the <BR>discussion on June 28th 1999 on linux-kernel, in which people <BR>propose setting up a testbed that can be used for ongoing benchmarks. <BR> <BR>There appears to be interest in this direction from the NSF, too; see <BR>the Web100 project. <BR> <BR>With that in mind, here are a few notes on how to configure operating <BR>systems and write code to support thousands of clients. The <BR>discussion centers around Unix-like operating systems, for obvious <BR>reasons. <BR> <BR>Book to Read First <BR> <BR>If you haven't read it already, go out and get a copy of Unix Network <BR>Programming : Networking Apis: Sockets and Xti (Volume <BR>1) by the late W. Richard Stevens. It describes many of the I/O <BR>strategies and pitfalls related to writing high-performance servers. <BR>It even talks about the 'thundering herd' problem. <BR> <BR>I/O Strategies <BR> <BR>There seem to be four ways of writing a fast web server to handle many <BR>clients: <BR> <BR> 1.Build the server code into the kernel. Novell and Microsoft are <BR>both said to have done this at various times, at least one <BR> NFS implementation does this, and khttpd does this for Linux and <BR>static web pages. <BR> The linux-kernel list has been discussing the pros and cons of this <BR> approach, and the consensus seems to be instead of <BR> moving web servers into the kernel, the kernel should have the <BR>smallest possible hooks added to improve web server <BR> performance. That way, other kinds of servers can benefit. See e.g. <BR> Zach Brown's remarks about userland vs. kernel http <BR> servers. <BR> <BR> 2.serve one client with each server thread, and let read() and <BR>write() block. (This is the only model supported by Java.) <BR> <BR> 3.serve many clients with each server process or thread, set <BR>nonblocking mode on all network handles, and use select() or <BR> poll() to tell which network handle has data waiting. This is the <BR>traditional favorite. It's still being improved; see e.g. Niels <BR> Provos' benchmarks with hinting poll and thttpd. <BR> An important bottleneck in this method is that read() or sendfile() <BR> from disk blocks if the page is not in core at the moment; <BR> setting nonblocking mode on a disk file handle has no effect. <BR>Same thing goes for memory-mapped disk files. The first time <BR> a server needs disk I/O, its process blocks, all clients must wait, <BR> and that raw nonthreaded performance goes to waste. <BR> Worker threads or processes that do the disk I/O can get around <BR>this bottleneck. One approach is to use memory-mapped <BR> files, and if mincore() indicates I/O is needed, ask a worker to do <BR> the I/O, and continue handling network traffic. Jef <BR> Poskanzer mentions that Pai, Druschel, and Zwaenepoel's Flash web <BR>server uses this trick; they gave a talk at Usenix '99 <BR> on it. It looks like mincore() is available in BSD-derived Unixes <BR>like FreeBSD and Solaris, but is not part of the Single Unix <BR> Specification. <BR> <BR> 4.serve many clients with each server process or thread, and use <BR>asynchronous I/O to avoid blocking. This has not yet <BR> become popular, possibly because of poorly designed asynchronous <BR>I/O interfaces. Zach Brown (author of HoserFTPD) <BR> thinks this might now be the way to go for highest performance; see <BR> his 14 April 1999 post to hftpd-users. <BR> There are several flavors of asynchronous I/O: <BR> the aio_ interface (scroll down from that link to <BR>"Asynchronous input and output"), which associates a signal and <BR> value with each I/O operation. Signals and their values are <BR>queued and delivered efficiently to the user process. This <BR> is from the POSIX 1003.1b realtime extensions, and is also <BR>in the Single Unix Specification, version 2, and in glibc <BR> 2.1. However, the generic glibc 2.1 implementation may have <BR>been written for standards compliance rather than <BR> performance. <BR> <BR> Much of the overhead of calling poll() can be eliminated by <BR>using fcntl(fd, F_SETSIG, signum), which associates a <BR> signal with each file descriptor, and raises that signal <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -