| ||||||
| 6/1 |
| 2007/11/27-30 [Computer/SW/Languages/C_Cplusplus, Computer/SW/OS/Solaris] UID:48701 Activity:high |
11/27 I'm using select to do a nonblocking check to see if a single socket
has anything to read off it. Problem is, I can have up to 12228
file descriptors, and Linux fd_set only supports up to 4096. Any idea
what I can do about this? (Or a better solution?) -jrleek
\- 1. who are you
2. i am busy this week and you didnt mention language
[i am not fmailar with stuff like java nio] but you might
look at this ucb/cs paper ... matt welsh et al "a design
framework for highly scalable systems" as well as
some of the discussion around libevent.
see the links and graph at http://monkey.org/~provos/libevent
\_ Ah, the program is all in 'C', but it needs to run on multiple
Unix variants. -jrleek
\_ Have you profiled it? Can you port to python or another
scripting language with reasonable performance (alas, not
ruby at this time)? -dans
ruby at this time)? At http://Slide.com, a hot startup in
downtown San Francisco (we're hiring!), we open AND
close millions of socket connections every day. -dans
\_ How could I profile it? This isn't a webserver, it's a
server that accepts, and acts on, messages based on a
protocol I wrote. (Over TCP). In this case, I need to
know about the performance of a tiny part of the code.
I'm not sure how to get that information. gprof, for
example, doesn't seem to allow me to choose just a small
section to profile, and lacks the necessary resoluton
anyway. -jrleek
\_ What you want is a profiling tool that doesn't work
via random sampling but that lets you add profiling
hooks into your code. I've written some homegrown
things like this in the past to profile very tight
loops in massive projects, but I'm sure there are
plenty of better tools out there if you poke around.
\_ Hint: leek >> dans. Why are you listening to his
babbling?
\_ Well, I have a lot to learn about network
programming, so I'll take what I can get. Thanks
for the compliment though. -jrleek
\_ Alas, I don't have any better suggestion that
gprof, though there must be better tools out
there. Another alternative would be to compile
the source, look at the ASM output and try to
hand optimize. Consider that a WAY last
resort, and not worth pursuing unless you're
already a fan of ASM. Two problems though:
there. Another alternative would be to
compile the source, look at the ASM output
and try to hand optimize. Consider that a
WAY last resort, and not worth pursuing unless
you're already a fan of ASM. Two problems
though:
a) it doesn't really scale if you need to
target multiple platforms and b) it's actually
tough to beat a *good* modern optimizing
compiler even if you really know what you're
doing. -dans
\_ UPDATE: I just asked one of the guru's and
he responded, 'books? what are those' see:
http://www.kegel.com/c10k.html
It's more of a jumping off point, but it will
at least give you tools to work with and
references potential implementations. -dans
\_ Hint: In the last three years have you...
a) worked on a project with me?
b) read or hacked any code I've written?
c) used a service based on my code or systems I
administered?
Unless you can answer yes to at least two, you
have NO FUCKING IDEA WHAT YOU'RE TALKING ABOUT.
Why two? Because I built the systems half (as
opposed to the network/routing half) of the
anycast DNS rig that runs the roots for over
fifty ccTLD's including, amusingly enough, .cx.
Thus, the answer to c) is almost always yes.
-dans
\_ Use poll() instead of select, or do multiple selects with several
different fd_sets . -ERic
\_ Can you increase the max size of fd_set in /proc? I'm guessing not,
but couldn't hurt to look. Also, using select on that many file
descriptors will probably result in sucky performance. -dans
\_ Do you know where I can read up on getting really good
performance out of the POSIX tcp codes?
\_ I wish I did. Most of what I know is a collection of voodoo
and lore. It's not super complicated, basically you want to
use non-blocking sockets and poll. Also, avoid threads
unless you know what you're doing. Writing correct threaded
code is hard, writing high-performance threaded code is even
harder. On Linux, processes are basically threads, but with
processes you don't have to handle any locking crap. -dans
\_ epoll (linux) or kqueue (bsd)
\_ Unfortunately, it needs to run on AIX (IBM's Unix) as well.
\- arent you that fellow at livermore? if this is going to
run on ibm big iron, maybe if you have a "user services"
group they will know this. cray and ibm have some people
group they will know this. cray and ibm have had some people
stationed here as part of nersc. i am familar with assos,
fleebsd, and solaris [/dev/poll] but not aix. btw some of
the select vs poll people seem to be unaware of many
places where the interface is different, but under the hood
they are the same thing. --psb
fleebsd, and solaris [/dev/poll] but not aix. --psb
\- i have never heard of/used this [i no longer
work on aix] but check this out:
http://tinyurl.com/26z9jf [pollset]
often i would think if there was something
that was obscure it probably wouldnt be that
good, but in this case 1. ibm has a history
of sitting on good things that fail due to
obscurity 2. i'm not in the loop [no pun
intended] any more on ibm stuff --fmr ibm person
\_ We do have such a group, but they don't know much about
TCP. It's kind of an odd thing to be doing. I wrote this
TCP implementation as a proof-of-concept, but we've never
gotten to money to do something better, so I just keep
trying to improve it incrementally. -jrleek |
| 6/1 |
|
| monkey.org/~provos/libevent -> monkey.org/~provos/libevent/ Honeyd The libevent API provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. Furthermore, libevent also support callbacks due to signals or regular timeouts. libevent is meant to replace the event loop found in event driven network servers. An application just needs to call event_dispatch() and then add or remove events dynamically without having to change the event loop. The internal event mechanism is completely independent of the exposed event API, and a simple update of libevent can provide new functionality without having to redesign the applications. As a result, Libevent allows for portable application development and provides the most scalable event notification mechanism available on an operating system. Libevent can also be used for multi-threaded applications; GPG Sig - Release 2007-09-24 Fix compilation on Solaris; from Magne Mahre Add a "Date" header to HTTP responses when it's missing, as required by HTTP 11 Original Patch from Ralph Moritz. Fix a memory leak in which failed HTTP connections whould not free the request object. from Trond Norbye Recalculate pending events properly when reallocating event array on Solaris; Benchmark Performance comparison using different event notification mechansims in Libevent. We declare interest in a large number of connections of which most are cold and only a few are active. The benchmark measures how long it takes to serve one active connection and exposes scalability issues of traditional interfaces like select or poll. The benchmark measures how long it takes to serve one hundred active connections that chain writes to new connections until thousand writes and reads have happened. Contributions If you like, use or appreciate libevent, you can contribute to continued development of the library. Funds are going to be used for development infrastructure. Contribution: USD Make payments with PayPal - it's fast, free and secure! |
| www.kegel.com/c10k.html Help save the best Linux news source on the web -- subscribe to Linux Weekly News! It's time for web servers to handle ten thousand clients simultaneously, don't you think? You can buy a 1000MHz machine with 2 gigabytes of RAM and an 1000Mbit/sec Ethernet card for $1200 or so. Let's see - at 20000 clients, that's 50KHz, 100Kbytes, and 50Kbits/sec per client. It shouldn't take any more horsepower than that to take four kilobytes from the disk and send them to the network once a second for each of twenty thousand clients. com, actually handled 10000 clients simultaneously through a Gigabit Ethernet pipe. being offered by several ISPs, who expect it to become increasingly popular with large business customers. And the thin client model of computing appears to be coming back in style -- this time with the server out on the Internet, serving thousands of clients. With that in mind, here are a few notes on how to configure operating systems and write code to support thousands of clients. The discussion centers around Unix-like operating systems, as that's my personal area of interest, but Windows is also covered a bit. presentation about network scalability, complete with benchmarks comparing various networking system calls and operating systems. One of his observations is that the 26 Linux kernel really does beat the 24 kernel, but there are many, many good graphs that will give the OS developers food for thought for some time. Unix Network Programming : Networking Apis: Sockets and Xti (Volume 1) by the late W Richard Stevens. It describes many of the I/O strategies and pitfalls related to writing high-performance servers. ACE, a heavyweight C++ I/O framework, contains object-oriented implementations of some of these I/O strategies and many other useful things. In particular, his Reactor is an OO way of doing nonblocking I/O, and Proactor is an OO way of doing asynchronous I/O. libevent is a lightweight C I/O framework by Niels Provos. It supports kqueue and select, and soon will support poll and epoll. It's level-triggered only, I think, which has both good and bad sides. Poller is a lightweight C++ I/O framework that implements a level-triggered readiness API using whatever underlying readiness API you want (poll, select, /dev/poll, kqueue, or sigio). benchmarks that compare the performance of the various APIs. This document links to Poller subclasses below to illustrate how each of the readiness APIs can be used. rn is a lightweight C I/O framework that was my second try after Poller. It's lgpl (so it's easier to use in commercial apps) and C (so it's easier to use in non-C++ apps). a paper in April 2000 about how to balance the use of worker thread and event-driven techniques when building scalable servers. The paper describes part of his Sandstorm I/O framework. library - an async socket, file, and pipe I/O library for Windows I/O Strategies Designers of networking software have many options. Here are a few: * Whether and how to issue multiple I/O calls from a single thread + Don't; use blocking/synchronous calls throughout, and possibly use multiple threads or processes to achieve concurrency + Use nonblocking calls (eg write() on a socket set to O_NONBLOCK) to start I/O, and readiness notification (eg poll() or /dev/poll) to know when it's OK to start the next I/O on that channel. Build the server code into the kernel 1 Serve many clients with each thread, and use nonblocking I/O and level-triggered readiness notification ... set nonblocking mode on all network handles, and use select() or poll() to tell which network handle has data waiting. With this scheme, the kernel tells you whether a file descriptor is ready, whether or not you've done anything with that file descriptor since the last time the kernel told you about it. That's why it's important to use nonblocking mode when using readiness notification. An important bottleneck in this method is that read() or sendfile() from disk blocks if the page is not in core at the moment; setting nonblocking mode on a disk file handle has no effect. The first time a server needs disk I/O, its process blocks, all clients must wait, and that raw nonthreaded performance goes to waste. This is what asynchronous I/O is for, but on systems that lack AIO, worker threads or processes that do the disk I/O can also get around this bottleneck. One approach is to use memory-mapped files, and if mincore() indicates I/O is needed, ask a worker to do the I/O, and continue handling network traffic. in November 2003 on the freebsd-hackers list, Vivek Pei et al reported very good results using system-wide profiling of their Flash web server to attack bottlenecks. One bottleneck they found was mincore (guess that wasn't such a good idea after all) Another was the fact that sendfile blocks on disk access; they improved performance by introducing a modified sendfile() that return something like EWOULDBLOCK when the disk page it's fetching is not yet in core. There are several ways for a single thread to tell which of a set of nonblocking sockets are ready for I/O: * The traditional select() Unfortunately, select() is limited to FD_SETSIZE handles. This limit is compiled in to the standard library and user programs. benchmarks) for an example of how to use poll() interchangeably with other readiness notification schemes. The idea behind /dev/poll is to take advantage of the fact that often poll() is called many times with the same arguments. With /dev/poll, you get an open handle to /dev/poll, and tell the OS just once what files you're interested in by writing to that handle; from then on, you just read the set of currently ready file descriptors from that handle. according to Sun, at 750 clients, this has 10% of the overhead of poll(). Various implementations of /dev/poll were tried on Linux, but none of them perform as well as epoll, and were never really completed. kqueue() can specify either edge triggering or level triggering. It then assumes you know the file descriptor is ready, and will not send any more readiness notifications of that type for that file descriptor until you do something that causes the file descriptor to no longer be ready (eg until you receive the EWOULDBLOCK error on a send, recv, or accept call, or a send or recv transfers less than the requested number of bytes). When you use readiness change notification, you must be prepared for spurious events, since one common implementation is to signal readiness whenever any packets are received, regardless of whether the file descriptor was already ready. It's a bit less forgiving of programming mistakes, since if you miss just one event, the connection that event was for gets stuck forever. Nevertheless, I have found that edge-triggered readiness notification made programming nonblocking clients with OpenSSL easier, so it's worth trying. There are several APIs which let the application retrieve 'file descriptor became ready' notifications: * kqueue() This is the recommended edge-triggered poll replacement for FreeBSD (and, soon, NetBSD). To change the events you are listening for, or to get the list of current events, you call kevent() on the descriptor returned by kqueue(). It can listen not just for socket readiness, but also for plain file readiness, signals, and even for I/O completion. Note: as of October 2000, the threading library on FreeBSD does not interact well with kqueue(); evidently, when kqueue() blocks, the entire process blocks, not just the calling thread. This is just like the realtime signal readiness notification, but it coalesces redundant events, and has a more efficient scheme for bulk event retrieval. A patch for the older version of epoll is available for the 24 kernel. unifying epoll, aio, and other event sources on the linux-kernel mailing list around Halloween 2002. It may yet happen, but Davide is concentrating on firming up epoll in general first. some recent discussion * Drepper's New Network Interface (proposal for Linux 26+) At OLS 2006, Ulrich Drepper proposed a new high-speed asynchronous networking API. LWN article from July 22 * Realtime Signals This is the recommended edge-triggered poll replacemen... |
| tinyurl.com/26z9jf -> publib.boulder.ibm.com/infocenter/systems/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/pollset.htm FRAME: BannerFrame FRAME: TabsFrame FRAME: HelpFrame |
| Slide.com -> www.slide.com/ com or any website Slide Shows Make a Slide Show Make a Slide Show and tell the world about yourself. Make a Guestbook SkinFlix Download Slide Screensaver Personalize YouTube clips with skins and more. Screensaver Download Slide Screensaver Watch slideshows, videos, hotties, and more. |