I am pleased to report another milestone was reached in the Zn project.
The default implementation for an HTTP Server is now a multi-threaded (forking) keep-alive implementation called ZnMultiThreadedServer. It passes my initial concurrent load tests. ZnServer is now a facade. This means that all features (test server, static file server, monticello server, seaside adaptor, as well as all unit tests) are now using the new code. In addition, several useful features were added to the servers, including logging and lastRequest/lastResponse debugging hooks. Extra handlers were added to ZnDefaultServerDelegate (favicon, benchmark, random) which double as examples. Next up will be some benchmarking and optimalization. As always, users/testers are most welcome. For more details: http://www.squeaksource.com/ZincHTTPComponents.html http://homepage.mac.com/svc/Zinc-HTTP-Components/index.html http://homepage.mac.com/svc/Zinc-HTTP-Components/getting-started.html Sven |
Cool, this is the way to go!
As usual, test results, code critics, and ready made images are available here: http://hudson.lukas-renggli.ch/job/Zinc/ Lukas On 15 December 2010 17:04, Sven Van Caekenberghe <[hidden email]> wrote: > I am pleased to report another milestone was reached in the Zn project. > > The default implementation for an HTTP Server is now a multi-threaded (forking) keep-alive implementation called ZnMultiThreadedServer. It passes my initial concurrent load tests. ZnServer is now a facade. This means that all features (test server, static file server, monticello server, seaside adaptor, as well as all unit tests) are now using the new code. > > In addition, several useful features were added to the servers, including logging and lastRequest/lastResponse debugging hooks. Extra handlers were added to ZnDefaultServerDelegate (favicon, benchmark, random) which double as examples. > > Next up will be some benchmarking and optimalization. As always, users/testers are most welcome. > > For more details: > > http://www.squeaksource.com/ZincHTTPComponents.html > > http://homepage.mac.com/svc/Zinc-HTTP-Components/index.html > > http://homepage.mac.com/svc/Zinc-HTTP-Components/getting-started.html > > Sven > > > -- Lukas Renggli www.lukas-renggli.ch |
On 15 Dec 2010, at 17:11, Lukas Renggli wrote: > As usual, test results, code critics, and ready made images are available here: > > http://hudson.lukas-renggli.ch/job/Zinc/ I must say that I am quite addicted to your Hudson server, almost every time I check in I go look at the page to see how it rebuilds. It is really useful to have an integration server like that, and I can image it must be real fun for the (core) Pharo team as integration is one of their main issues. And it is instructive to so see all the Smalltalk scripting going on. Sven |
Sven
our objectives is that any package published in the metacello repositories (once metacello 1.0 is released) should get treated by the pharo hudson server. Eventually we want to have also the VM automatically generated. I should learn how to set more projects :) Stef >> As usual, test results, code critics, and ready made images are available here: >> >> http://hudson.lukas-renggli.ch/job/Zinc/ > > I must say that I am quite addicted to your Hudson server, almost every time I check in I go look at the page to see how it rebuilds. > > It is really useful to have an integration server like that, and I can image it must be real fun for the (core) Pharo team as integration is one of their main issues. And it is instructive to so see all the Smalltalk scripting going on. > > Sven > > |
In reply to this post by Sven Van Caekenberghe
On 15.12.2010 17:04, Sven Van Caekenberghe wrote:
> I am pleased to report another milestone was reached in the Zn project. > > The default implementation for an HTTP Server is now a multi-threaded (forking) keep-alive implementation called ZnMultiThreadedServer. It passes my initial concurrent load tests. ZnServer is now a facade. This means that all features (test server, static file server, monticello server, seaside adaptor, as well as all unit tests) are now using the new code. > > In addition, several useful features were added to the servers, including logging and lastRequest/lastResponse debugging hooks. Extra handlers were added to ZnDefaultServerDelegate (favicon, benchmark, random) which double as examples. > > Next up will be some benchmarking and optimalization. As always, users/testers are most welcome. This is with the AJPFastRequestHandler from the AJP-Benchmark package from http://www.squeaksource.com/ajp (there are no dependencies to AJP). ab -k -c 10 -n 10000 http://127.0.0.1:8080/fast This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: Zinc Server Hostname: 127.0.0.1 Server Port: 8080 Document Path: /fast Document Length: 16294 bytes Concurrency Level: 10 Time taken for tests: 5.624 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Keep-Alive requests: 10000 Total transferred: 164560000 bytes HTML transferred: 162940000 bytes Requests per second: 1778.08 [#/sec] (mean) Time per request: 5.624 [ms] (mean) Time per request: 0.562 [ms] (mean, across all concurrent requests) Transfer rate: 28574.28 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 0 6 17.1 1 155 Waiting: 0 6 17.1 0 155 Total: 0 6 17.1 1 155 Percentage of the requests served within a certain time (ms) 50% 1 66% 1 75% 1 80% 1 90% 15 95% 44 98% 70 99% 89 100% 155 (longest request) Not too shabby. Cheers Philippe |
Philippe,
First of all, thanks a lot for taking the time doing these benchmarks. I know you are very well placed to do these test, so I am honored you did. Second, although this is a static page bypassing encoding, the results are very impressive indeed. It is still Seaside and a 16KB page. Furthermore, all request completed successfully with a good distribution. This makes me quite happy! I do however suspect some serious hardware being used. Could you elaborate on the hardware, OS, VM and other details ? Regards, Sven On 17 Dec 2010, at 20:52, Philippe Marschall wrote: > On 15.12.2010 17:04, Sven Van Caekenberghe wrote: >> I am pleased to report another milestone was reached in the Zn project. >> >> The default implementation for an HTTP Server is now a multi-threaded (forking) keep-alive implementation called ZnMultiThreadedServer. It passes my initial concurrent load tests. ZnServer is now a facade. This means that all features (test server, static file server, monticello server, seaside adaptor, as well as all unit tests) are now using the new code. >> >> In addition, several useful features were added to the servers, including logging and lastRequest/lastResponse debugging hooks. Extra handlers were added to ZnDefaultServerDelegate (favicon, benchmark, random) which double as examples. >> >> Next up will be some benchmarking and optimalization. As always, users/testers are most welcome. > > This is with the AJPFastRequestHandler from the AJP-Benchmark package > from http://www.squeaksource.com/ajp (there are no dependencies to AJP). > > ab -k -c 10 -n 10000 http://127.0.0.1:8080/fast > This is ApacheBench, Version 2.3 <$Revision: 655654 $> > Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ > Licensed to The Apache Software Foundation, http://www.apache.org/ > > Benchmarking 127.0.0.1 (be patient) > Completed 1000 requests > Completed 2000 requests > Completed 3000 requests > Completed 4000 requests > Completed 5000 requests > Completed 6000 requests > Completed 7000 requests > Completed 8000 requests > Completed 9000 requests > Completed 10000 requests > Finished 10000 requests > > > Server Software: Zinc > Server Hostname: 127.0.0.1 > Server Port: 8080 > > Document Path: /fast > Document Length: 16294 bytes > > Concurrency Level: 10 > Time taken for tests: 5.624 seconds > Complete requests: 10000 > Failed requests: 0 > Write errors: 0 > Keep-Alive requests: 10000 > Total transferred: 164560000 bytes > HTML transferred: 162940000 bytes > Requests per second: 1778.08 [#/sec] (mean) > Time per request: 5.624 [ms] (mean) > Time per request: 0.562 [ms] (mean, across all concurrent requests) > Transfer rate: 28574.28 [Kbytes/sec] received > > Connection Times (ms) > min mean[+/-sd] median max > Connect: 0 0 0.0 0 0 > Processing: 0 6 17.1 1 155 > Waiting: 0 6 17.1 0 155 > Total: 0 6 17.1 1 155 > > Percentage of the requests served within a certain time (ms) > 50% 1 > 66% 1 > 75% 1 > 80% 1 > 90% 15 > 95% 44 > 98% 70 > 99% 89 > 100% 155 (longest request) > > Not too shabby. > > Cheers > Philippe |
In reply to this post by Philippe Marschall-2-3
Hi philippe
thanks for helping sven. Now for the blind like me. What do the tool says? Because not too shabby is difficult to fully interpret :) Stef |
In reply to this post by Sven Van Caekenberghe
On 17.12.2010 23:54, Sven Van Caekenberghe wrote:
> Philippe, > > First of all, thanks a lot for taking the time doing these benchmarks. I know you are very well placed to do these test, so I am honored you did. > > Second, although this is a static page bypassing encoding, the results are very impressive indeed. It is still Seaside and a 16KB page. Furthermore, all request completed successfully with a good distribution. This makes me quite happy! > > I do however suspect some serious hardware being used. Could you elaborate on the hardware, OS, VM and other details ? Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz Linux 2.6.36 (64bit) Cog r2316 Pharo 1.1.1 (no memory tweaks) Basically an almost four year old Linux box. Cheers Philippe |
In reply to this post by Stéphane Ducasse
On 18.12.2010 09:17, Stéphane Ducasse wrote:
> Hi philippe > > thanks for helping sven. Now for the blind like me. What do the tool says? > Because not too shabby is difficult to fully interpret :) Benchmarks always are ;-) Management summary it does: ~30 Mbytes/sec (bytes not bits) and 1778 requests per second. Now comes a long section why this is unrealistic and you can't expect this performance in the real world. You can look at the benchmark as an upper bound of what the server is capable of. It makes 10000 requests using 10 concurrent, recycled connections to the local machine. On the Smalltalk side there's a simple Seaside request handler that takes a 16k byte array (the www.seaside.st homepage) and writes it to the response. Note that a smaller page would obviously result in more requests per second and less throughput while you would expect to see the opposite from a bigger page. There are no sessions, continuations, rendering or encoding involved because the idea is to stress the sever, not Seaside. On the other hand conversion to and from Seaside requests and responses happens as well as the whole context and handler chain are set up. In a real world scenario you would spend much more time in Seaside and the back end of your application¹. The connections would be slower, each connection would not make that may requests and you'd have network latency. To get an idea what impact latency can have see [1]. Other points to note: - The server does not lose any requests. This is a problem I've run into using the same benchmark on other Smalltalk servers. - Most requests come back fairly quickly, 80% in 1 ms. The longest takes 155ms (maybe GC interference). One important point this benchmark does not cover is how well does it clean up hanging or stale connections. This is a much bigger issue in production than a few Mbytes/sec. To reproduce load the package AJP-Benchmark from [2], register AJPFastRequestHandler (see class side), hit the page once with you browser so that the cache gets initialized and run: ab -k -c 10 -n 10000 http://127.0.0.1:8080/fast (ab comes with every Mac) There are other request handlers in there that do encoding and rendering which obviously results in worse performance but more realistic numbers. They are designed to stress Seaside rather than the server. [1] http://blogs.webtide.com/gregw/entry/lies_damned_lies_and_benchmarks [2] http://www.squeaksource.com/ajp ¹ you could use a caching filter though that does a lookup in a dictionary Cheers Philippe |
thanks philippe
now the executive summary: does it mean that zinc is well positioned compared to others? Stef On Dec 18, 2010, at 11:30 AM, Philippe Marschall wrote: > On 18.12.2010 09:17, Stéphane Ducasse wrote: >> Hi philippe >> >> thanks for helping sven. Now for the blind like me. What do the tool says? >> Because not too shabby is difficult to fully interpret :) > > Benchmarks always are ;-) > > Management summary it does: ~30 Mbytes/sec (bytes not bits) and 1778 > requests per second. Now comes a long section why this is unrealistic > and you can't expect this performance in the real world. > > You can look at the benchmark as an upper bound of what the server is > capable of. It makes 10000 requests using 10 concurrent, recycled > connections to the local machine. > > On the Smalltalk side there's a simple Seaside request handler that > takes a 16k byte array (the www.seaside.st homepage) and writes it to > the response. Note that a smaller page would obviously result in more > requests per second and less throughput while you would expect to see > the opposite from a bigger page. There are no sessions, continuations, > rendering or encoding involved because the idea is to stress the sever, > not Seaside. On the other hand conversion to and from Seaside requests > and responses happens as well as the whole context and handler chain are > set up. > > In a real world scenario you would spend much more time in Seaside and > the back end of your application¹. The connections would be slower, each > connection would not make that may requests and you'd have network > latency. To get an idea what impact latency can have see [1]. > > Other points to note: > - The server does not lose any requests. This is a problem I've run into > using the same benchmark on other Smalltalk servers. > - Most requests come back fairly quickly, 80% in 1 ms. The longest takes > 155ms (maybe GC interference). > > One important point this benchmark does not cover is how well does it > clean up hanging or stale connections. This is a much bigger issue in > production than a few Mbytes/sec. > > To reproduce load the package AJP-Benchmark from [2], register > AJPFastRequestHandler (see class side), hit the page once with you > browser so that the cache gets initialized and run: > > ab -k -c 10 -n 10000 http://127.0.0.1:8080/fast > (ab comes with every Mac) > > There are other request handlers in there that do encoding and rendering > which obviously results in worse performance but more realistic numbers. > They are designed to stress Seaside rather than the server. > > [1] http://blogs.webtide.com/gregw/entry/lies_damned_lies_and_benchmarks > [2] http://www.squeaksource.com/ajp > > ¹ you could use a caching filter though that does a lookup in a dictionary > > Cheers > Philippe > > > > > |
In reply to this post by Philippe Marschall-2-3
On 18 Dec 2010, at 09:25, Philippe Marschall wrote: > Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz > Linux 2.6.36 (64bit) > Cog r2316 > Pharo 1.1.1 (no memory tweaks) > > Basically an almost four year old Linux box. Philippe, Is that a desktop machine with a normal interactive load, or a server machine ? How much RAM ? Do you run the image headless ? On my development machine (Mac Book Pro, Intel Core 2 Duo 2.4 Ghz, 4 GB RAM, Mac OS X 10.6.5, Squeak 5.8b12, normal image, normal desktop load with lots of apps), I cannot get even close to your numbers (/bytes/16384 is a binary unencoded response of 16Kb direct from Zn): [sven@voyager:~]$ ab -k -n 10000 -c 10 http://127.0.0.1:1701/bytes/16384 This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: Zinc Server Hostname: 127.0.0.1 Server Port: 1701 Document Path: /bytes/16384 Document Length: 16384 bytes Concurrency Level: 10 Time taken for tests: 14.829 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Keep-Alive requests: 10000 Total transferred: 165610000 bytes HTML transferred: 163840000 bytes Requests per second: 674.37 [#/sec] (mean) Time per request: 14.829 [ms] (mean) Time per request: 1.483 [ms] (mean, across all concurrent requests) Transfer rate: 10906.48 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 1 15 3.1 14 67 Waiting: 0 15 2.8 14 67 Total: 1 15 3.1 14 67 Percentage of the requests served within a certain time (ms) 50% 14 66% 15 75% 16 80% 16 90% 17 95% 18 98% 21 99% 25 100% 67 (longest request) This is no more than 1/3 of your results. I will be trying to find time to get a recent Cog VM on a Linux server machine using a headless deploy image and run benchmarks there. Thanks for the feedback and for pushing this. Sven |
In reply to this post by Philippe Marschall-2-3
On 18 Dec 2010, at 11:30, Philippe Marschall wrote: > Benchmarks always are ;-) [...] Excellent writeup, once again. I think / I'm pretty confident that the cleanup goes well, as long as Socket[Stream] respects its timeout (currently set at 10s for all streams, maybe 5s would be better for the server) and throws ConnectionTimedOut and ConnectionClosed exceptions reliably. Doing Smalltalk garbageCollect. Socket allInstances. before and after the benchmarks shows no leaking. But then again, the HTTP request parsing could be made more bullet proof. Adding a load balancer in front of Zn that also sanitizes requests would be a good idea for production setups. Sven |
In reply to this post by Stéphane Ducasse
On 18.12.2010 11:43, Stéphane Ducasse wrote:
> thanks philippe > > now the executive summary: does it mean that zinc is well positioned compared to others? That's a much more difficult question. First what do you mean by "others"? Second raw performance is often not the most important criteria to chose a web server. Others like reliability and feature set are often more important. And let's be honest, if raw performance was your most important criteria, Pharo probably wouldn't be your first choice anyway. Cheers Philippe |
yes but you know what I mean :)
Comanche,.... WebClient.... Swazoo On Dec 18, 2010, at 1:51 PM, Philippe Marschall wrote: > On 18.12.2010 11:43, Stéphane Ducasse wrote: >> thanks philippe >> >> now the executive summary: does it mean that zinc is well positioned compared to others? > > That's a much more difficult question. First what do you mean by > "others"? Second raw performance is often not the most important > criteria to chose a web server. Others like reliability and feature set > are often more important. And let's be honest, if raw performance was > your most important criteria, Pharo probably wouldn't be your first > choice anyway. > > Cheers > Philippe > > |
In reply to this post by Sven Van Caekenberghe
On 18.12.2010 11:59, Sven Van Caekenberghe wrote:
> > On 18 Dec 2010, at 09:25, Philippe Marschall wrote: > >> Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz >> Linux 2.6.36 (64bit) >> Cog r2316 >> Pharo 1.1.1 (no memory tweaks) >> >> Basically an almost four year old Linux box. > > Philippe, > > Is that a desktop machine with a normal interactive load, or a server machine ? How much RAM ? Do you run the image headless ? > > On my development machine (Mac Book Pro, Intel Core 2 Duo 2.4 Ghz, 4 GB RAM, Mac OS X 10.6.5, Squeak 5.8b12, normal image, normal desktop load with lots of apps), I cannot get even close to your numbers (/bytes/16384 is a binary unencoded response of 16Kb direct from Zn): > > ... > > This is no more than 1/3 of your results. > I will be trying to find time to get a recent Cog VM on a Linux server machine using a headless deploy image and run benchmarks there. > Thanks for the feedback and for pushing this. That's a desktop Linux with 2 GB of RAM, Gnome and Thunderbird running. Normal headed Pharo image. I have a similar Mac Book Pro where I get somewhat lower numbers than on the Linux box but not a 1/3. How big is your image? I noted that "fresh", small (20 - 30 MB) images are often faster. Is the response static or do you allocate a byte array for every response? Despite everything this benchmark is CPU limited. If you load AJPFastRequestHandler and Zinc-Seaside do you see any difference? I got my Cog VM from [1] [1] http://www.mirandabanda.org/files/Cog/VM/ Cheers Philippe |
In reply to this post by Sven Van Caekenberghe
On 18.12.2010 12:08, Sven Van Caekenberghe wrote:
> > On 18 Dec 2010, at 11:30, Philippe Marschall wrote: > >> Benchmarks always are ;-) > > > [...] > > Excellent writeup, once again. > > I think / I'm pretty confident that the cleanup goes well, as long as Socket[Stream] respects its timeout (currently set at 10s for all streams, maybe 5s would be better for the server) and throws ConnectionTimedOut and ConnectionClosed exceptions reliably. > > Doing > > Smalltalk garbageCollect. > Socket allInstances. > > before and after the benchmarks shows no leaking. > > But then again, the HTTP request parsing could be made more bullet proof. Adding a load balancer in front of Zn that also sanitizes requests would be a good idea for production setups. Yeah, in AJP I could save a lot of code because there's an Apache in front of it sanitizing the requests and managing the connections. Cheers Philippe |
In reply to this post by Philippe Marschall-2-3
Hey Philippe,
On 18 Dec 2010, at 17:20, Philippe Marschall wrote: > Is the response static or do you allocate a byte array for every > response? Despite everything this benchmark is CPU limited. You were right: I added caching (reuse on repeated requests) on repeated requests to my /bytes handler and I can now match your results on my machine (development image, interactive machine load): [sven@voyager:~]$ ab -k -n 10000 -c 10 http://127.0.0.1:1701/bytes/16384 This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: Zinc Server Hostname: 127.0.0.1 Server Port: 1701 Document Path: /bytes/16384 Document Length: 16384 bytes Concurrency Level: 10 Time taken for tests: 4.319 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Keep-Alive requests: 10000 Total transferred: 165610000 bytes HTML transferred: 163840000 bytes Requests per second: 2315.37 [#/sec] (mean) Time per request: 4.319 [ms] (mean) Time per request: 0.432 [ms] (mean, across all concurrent requests) Transfer rate: 37446.17 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 0 4 1.6 4 30 Waiting: 0 4 1.5 4 27 Total: 0 4 1.6 4 30 Percentage of the requests served within a certain time (ms) 50% 4 66% 5 75% 5 80% 5 90% 6 95% 7 98% 8 99% 9 100% 30 (longest request) Benchmarking is indeed fun (and very dangereous and a time sink). Sven |
Free forum by Nabble | Edit this page |