Opcode Cache for Dummies

tags:

PHP is an interpreted language. This means that each time a PHP generated page is requested, the server must read in the various files needed and "compile" them into something the machine can understand (opcode). A typical Drupal page requires more than a dozen of these bits of code be compiled.

Opcode cache mechanisms preserve this generated code in cache so that it need only be generated a single time to server hundreds or millions of subsequent requests.

Enabling opcode cache will reduce the time it takes to generate a page by up to 90%.

Vroom! PHP is known for its blazing speed. Why would you want to speed up your PHP applications even more? Well, first and foremost is the coolness factor. Next, you'll increase the capacity of your current server(s) many times over, thereby postponing the inevitable need to add new hardware as your site's popularity explodes. Lastly, high bandwidth, low latency visitors to your site who are currently seeing page load times in the 1-2 second range will be shocked to find your vamped up site serving up pages almost instantaneously. After enabling opcode cache on my own server, I saw page loads drop from about 1.5 seconds to as low as 300ms. Now that's good fun the whole family can enjoy.

Opcode Cache Solutions

There are a number of opcode caching solutions. For a rundown on some of them, read this article. After a bit of research and a lot of asking around, I concluded that Eaccelerator was the best choice for me. It's compatible with PHP5, is arguably the most popular of its kind, and is successfully used on sites getting far more traffic than you or I are ever likely to see.

Implementing Eaccelerator

This is the fun and exciting part. Implementing opcode cache is far easier than you might imagine. The only thing you'll need is admin (root) access to your server. If you're in a shared hosting environment, ask your service provider about implementing this feature if it is not in place already. These instructions apply to *nix environments only.

Poor Man's Benchmarking

If you would like to have some before and after numbers to show off to your friends, now is the time to get the 'before' numbers. Ideally, you will have access to a second host on the same local network as your server so that the running of the test does not affect the results. For those of us without such access, we'll just have to run the test on the actual webserver, so don't submit these results in your next whitepaper:

Apache comes with a handy benchmarking tool called "ab". This is what I use for quick and dirty testing. From the command line, simply type in the following:

ab -n 1000 -c 10 http://[YOURSITE.COM]/

Here is a portion of the results I got on my own test:

    Concurrency Level:      10
Time taken for tests:   78.976666 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      13269256 bytes
HTML transferred:       12911899 bytes
Requests per second:    12.66 [#/sec] (mean)
Time per request:       789.767 [ms] (mean)
Time per request:       78.977 [ms] (mean, across all concurrent requests)
Transfer rate:          164.07 [Kbytes/sec] received
Connection Times (ms)
min  mean[+/-sd] median   max
Connect:        0    7  51.3      0     617
Processing:    77  725 1704.4    300   21390
Waiting:        0  673 1697.5    266   21383
Total:         77  732 1706.2    307   21390
Percentage of the requests served within a certain time (ms)
50%    307
66%    468
75%    625
80%    639
90%    805
95%   3808
98%   6876
99%   8529
100%  21390 (longest request)

The single most useful number is 'Requests per second', which in my case was 12.66.

Download, Build and Install

First, download the source code.

Get it to your server and do the following (I'm assuming you have gcc on your system, if not, get it):

tar jxvf  eaccelerator-0.9.5.tar.bz2
cd eaccelerator-0.9.5
phpize
./configure
make
make install

Configure Apache and Restart

If you have an /etc/php.d directory, create the file /etc/php.d/eaccelerator.ini for your new settings. Alternatively, you can put them in your php.ini file. Your configuration should look something like this:

zend_extension="/usr/lib/php/modules/eaccelerator.so"
eaccelerator.shm_size="32"
eaccelerator.cache_dir="/var/cache/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"
eaccelerator.compress="1"
eaccelerator.compress_level="9"
eaccelerator.log_file = "/var/log/httpd/eaccelerator_log"
; eaccelerator.allowed_admin_path = "/var/www/html/control.php"

Adjust values according to your particular distribution. For more details on configuring eaccelerator, see the settings documentation.

See Eaccelerator in Action

The value eaccelerator.allowed_admin_path, if enabled, should point to a web accessible directory with a copy of 'control.php' (which comes with the eaccelerator source code). Edit this script, changing the username and password. You can then access this control panel and see exactly what eaccelerator is caching

See the results

After enabling Eaccelerator on devbee.com, I ran my benchmark again, and here are the results:

    Concurrency Level:      10
Time taken for tests:   10.472143 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      13129000 bytes
HTML transferred:       12773000 bytes
Requests per second:    95.49 [#/sec] (mean)
Time per request:       104.721 [ms] (mean)
Time per request:       10.472 [ms] (mean, across all concurrent requests)
Transfer rate:          1224.30 [Kbytes/sec] received
Connection Times (ms)
min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       4
Processing:    20  103  52.1     96     345
Waiting:       17   92  50.1     83     342
Total:         20  103  52.1     96     345
Percentage of the requests served within a certain time (ms)
50%     96
66%    122
75%    137
80%    147
90%    176
95%    201
98%    225
99%    248
100%    345 (longest request)

We are now serving up 95.49 requests per second. That's 754% increase in server capacity. Had I been able to run the tests from another machine on the same network, I believe the numbers would be even more dramatic.

This is sweet! Thanks for the guide!

great post, a little hard to read with some of the weird characters that didn’t transfer well, but other then that I enjoyed the brief quotes form the interview.

hey, I love this blog - i will try and keep up with it!! please keep more coming :)I wish I could start a blog but I don’t have much time. I consider your advice as very valuable.Really Great. :( Thanks,

Yes i agree with you. Nice blog and informative also.

Nice numbers! I'm curious, though, why you went with eaccelerator rather than APC. I've no personal experience with either, but I thought APC was the more PHP.net-endorsed one. What did "a bit of research and a lot of asking around" include to lead you to that conclusion?

Is PHP an interpreted or a compiled language?What compiler or interpreter does PHP use. Which version use it. How the code turns to program. thanks for the help...Anuya with thanks!!!

Because APC doesn't play well with others (Zend). Other benchmarks show eAccel to be about 10-15% faster than APC.

OH MY GOD. This is insane. I've got a teeny-tiny vps for dev with essentially zero horsepower, and I've gone from 5.31 rps to 39.62. I haven't tested much yet, so I can't say I'm 100% on this, but 8x faster... unbelievable. According to devel the math is even better. Light pages were loading at abou 115 pre-eaccelrator and now are consistently 12ms.

I can't wait to get this on the production servers.

UPDATE: I've finally taken the step to install this on the production servers, as I mentioned doing above. As one small benchmark, I've got an events calendar where I load drupal nodes via ajax... they're loading so fast (about 12ms) that you don't even need to show the user an ajax progress image/icon. The requests per second on apache bench also came out very well... about 10 pre-accelerator to 110 post (using the parameters from this article).

I am one happy dev.

That picture is insane, all for wheels off the ground! No seatbelts in those days too.

Your numbers show that enabling Eaccelerator has a dramatic effect on the increase in efficiency of your server. nice work.

Very important blog for webdesigners.I dont hav much idea about web designing but only I can appriciate your efforts.Thanks for sharing the info..thanks for this– you’re bookmarked...

I've got an events calendar where I load drupal nodes via ajax... they're loading so fast (about 12ms) that you don't even need to show the user an ajax progress image/icon. The requests per second on apache bench also came out very well... about 10 pre-accelerator to 110 post (using the parameters from this article). Great article thanks for this– you’re bookmarked...

Thanks for sharing the info.. It seems now i can improve my web rankings

i will keep to visit your site...................!

I have enabled both caching and css-optimizing in my drupal administration panel. This gives a very notably

this is very nice tips you can do it

Quite an intresting blog with intresting info.Great article thanks for this– you’re bookmarked... keep up the great work.

This article is so great. Thank's

That's great, but we won't use opcode caching engines because they tend to cause segmentation faults in Apache under high load. Memcache is a better solution, IMHO. I see this is a Drupal site - with the Cache Router module you can choose your poison. It even offers a basic file cache, which is surprisingly quick! =)

I needed a quick way to populate some projects with dummy, random data, ... I came across an issue with running APC, the opcode cache developed by Rasmus ...

Thanks a lot after visiting your blog i can understand the importance of the PHP...!

PHP is a scripting language originally designed for producing dynamic web pages. It has evolved to include a command line interface capability

I have a dummy site running with more than 6 billion pages.

useful information. i can use this to try on some of my online work. thanks. -Mike Costoev / Mill Creek Pictures

PHP is an interpreted language. This means that each time a PHP generated page is requested, the server must read in the various files needed and "compile" them into something the machine can understand (opcode). A typical Drupal page requires more than a dozen of these bits of code be compiled.
watch movies online

Good article about intermediate code caching. It is exactly something I was looking for, found it really helpful. Thanks a lot for sharing this useful information with the whole world.

Regards,
Gaurav