views:

357

answers:

4

I have a PHP file that gets HTML from Memcached and serves it to user. When I test it like this:

ab -n 1000 -c 100 http://website.com/test.php

It does 22 requests per second.

But when I put the same HTML to a html file and do this test:

ab -n 1000 -c 100 http://website.com/test.html

I get like 4500 requests per second.

I need to stick to PHP because first time I need to generate HTML and next times I just get generated one from Memcached. And moreover HTML I display is different for every other user (recognized based on $_GET ['user_id'] value). Is there any way to make RPS higher? Closer to serving plain HTML?

I use as a server Lighttpd.

+1  A: 

Chain of thoughts (to be continued....):
First I would test if the problem is triggered by or significantly worsened by concurrency. With your -n 1000 -c 100 test you had a ratio of 22/4500. What about -n 1000 -c 10 or -n 1000 -c 1?

Then I would try the same again + keeping track of memory consumption, disc i/o and cpu usage. Is any of this clearly the limiting factor?

Then I'd test simple php scripts:

  • an empty script
  • <?php echo 'x';
  • no script at all, but the contents of test.html copied over to test.php
  • only serving a small memcached item. As simple a script as possible, construct the memchached object and get an item, no test, no expiration, no add, only echo $mc->get(string $key)

How do those compare to test.html?

edit:

Let's take Web Server Performance Comparison: LiteSpeed 2.0 VS as a comparison point. The benchmark was performed "for" another "rivaling" webserver product but for the moment let's assume they weren't (too) biased ;-)

They had a

  • CPU: Single Intel Xeon 2.4GHz/533FSB/512KB L2 Cache
  • memory: 256MB ECC PC2700
  • Hard Drive: 36GB 10K RPM SCSI drive Seagate ST336607LW
  • NIC: on board Intel PRO/1000 Gigabit Adapter

The lighthttpd served 15475/s files of 100 bytes, 1593/s helloworld.php and 399/s phpinfo.php scripts (both fastcgi). That's a ration of ~ 1:10 (hello world) or 1:40 (phpinfo). "Your" ratio is 22:4500 ~ 1:200. And even stranger it doesn't change when the script changes. Your "real" script or an empty php script, no matter always 1:22. That raises the "strangeness factor" quite a bit (even though the tests are not identical).
First of all I would double-check if php was compiled with fastcgi-support, see http://www.fastcgi.com/docs/faq.html#PHP. Then I'd test "my" lighthttpd with a simple c/c++ fastcgi program as mentioned in the test, a real simple "hello world". There's an example at http://www.fastcgi.com/devkit/doc/fastcgi-prog-guide/ch2c.htm#4263. If this scales "well", i.e. significantly better than your php-fastcgi, I'd try it with a "barely running" php version, i.e. compiled with --disable-all and only those modules (re)actived and built-in that are necessary to start php and let it print "hello world". Also use the default php.ini. Does this change anything?

VolkerK
Thank you for answer. Here are results: "-c 10" gives 22 RPS, "-c 1" both gives 21 RPS.CPU usage is max. 60% and Memory max. 300 MB from 2 GB available. I don't know how to measure disc i/o usage.In all 4 test scenarios bulleted out I get 22 RPS too.
tomaszs
So this first series of tests had virtually no effect what-so-ever...
VolkerK
Thanks for your help. You're right: it seems to be php/lighttpd problem. So as you write before I recompile php i would like to check if it's compiled actually with fastcgi. How to check it?
tomaszs
In PHP 5.3 FastCGI is always enabled and cannot be disabled. Call your php executable from a shell with the -v parameter, e.g. `php-cgi -v`. It prints `cgi-fcgi` if fastcgi support is enabled and just `cgi` otherwise.
VolkerK
@VolkerK as you wrote I took a closer look at fcgi. It occurred that Its not enabled but available at my system. So i used this: http://www.cyberciti.biz/tips/lighttpd-php-fastcgi-configuration.html to update config. Next it ocurrent that it uses /etc/php.ini not /home/domain.com/httpdoc/php.ini. So i've updated first to be like the second one. Next i've checked if it works. And it worked. I've tested test.php and have now 1500 RPS. It's 68x faster. Thank you very very much! Just great. I'm very happy and glad to get help from expert. Greetings and have a nice day!!!
tomaszs
And at '-c 1000 -n 10000' i have 3000 RPS :)
tomaszs
That's a nice boost. And will probably postpone getting your hands dirty with the c plugin for a while :-)
VolkerK
A: 

You could try (psuedo code):

if file myfilecache/$user_$request_$today.html does not exist 
then do
     format page 
     write page to myfilecache/$user_$request_$today.html
done
redirect to myfilecache/$user_$request_$today.html

The file system makes is a pretty good cache and lightpd will do the actual work of serving up the page.

James Anderson
A: 

Going faster than script? Try writing plain html files and serving those. And make an "updater" script that updates your html files from time to time, or on a certain event if you really need speed like that.

Try using SSI in some places and see how that works out (http://httpd.apache.org/docs/1.3/howto/ssi.html)

Try using Eaccelerator (http://eaccelerator.net/ ) or APC (http://www.php.net/apc/) to speed up the script parser, but it wont do wonders on PHP5...

Make sure the physical server has enough free resources (FAST hdd, lots of ram, multiple-processors).

Its pretty normal that your script is slower than the html page:) Serving up the html page means a simple copy-of-the-file-over-the-wire. The php script means initializing the script engine, caching, parsing classes, functions, memory allocations, session locking/unlocking and saving, reading from the memcached server, reading config files.... for each of the requests...

Quamis
See answer to VolkerK - it's even for empty PHP
tomaszs
A: 

You might also want to consider putting a HTTP cache in front of your PHP server. This will reduce the load on your web server and will handle the re-sending of previously rendered pages for you.

See Varnish for example. Another option is Squid

Obviously these are not options if you are on shared hosting - in that case rendering to .html files is a great solution.

Tom Leys