For a large Drupal site, one of the biggest performance boosts one can do is to install an op-code cache/accelerator.
PHP op-code caches / Accelerators
Since PHP is an interpreted language, every page access has to load the script, parse it, compile it into op-codes, then execute it.
This load/parse/compile cycle can add up to a lot of processing time, specially when you have lots of page accesses.
Op-code caches/accelerators eliminate this load/parse/compile time, by doing so once, and keeping the compiled version of the script in memory (or disk) and use it next time a page requests this script.
This has two main benefits:
- Page processing times can be much less in many cases.
- Decreased load on server resources, mainly CPU time and memory consumption, which is important for a large site, or when a site suffers the Slashdot/Digg Effect.
These are compelling reasons to use an op-code cache.
Of course, an op-code cache will not help your site if your bottleneck in not CPU or memory. For example, if your bottleneck is in the database, or disk, the op-code cache will not directly help. However, since scripts start and end faster than without one, you may experience less contention in some cases.
Case study: Large Drupal site with APC and eAccelerator
Drupal as an application does a lot of processing for every page load. If you have lots of add on modules, then the processing is even more.
As a case study, a Drupal site that receives hundreds of thousands of page views per day was tested with and without an op-code cache.
The site runs on a Dual Opteron 246, 2 GB of memory, using Ubuntu Edgy Eft 6.10, Apache 2.0.55, PHP 5.1.6, and MySQL 5.0.24.
The following CPU and memory graphs were produced by Munin, a highly recommended near real time monitoring tool. Note that because the server has two CPUs, the scale is from 0 to 200% and not 100% as one would expect.
Resource Utilization without an op-code cache
Without an accelerator, the CPU utilization was as follows. You can see that during peak hours the server CPUs were consistently above 3/4 utilization (169% out of 200%), with an average of 1/2 (103% out of 200%).
As for memory utilization, here is the graph without any op-code cache. The important part is the green section (apps), which is the amount used by applications. The memory available is the blue (unused), and the file system cache (cache) is the orange part. You can see how the applications part moves up from 0.5GB to around 0.9 GB during peak hours.
Resource Utilization with eAccelerator 0.9.5.
After installing eAccelerator 0.9.5 from source, the CPU utilization was far less on a day with a comparable page views.
You can see that the maximum utilization was around 80% of 200%, with short spurts to 100% only. This means there is room for growth on the server now, instead of being at the brink of resource shortages.
And the memory utilization is also considerably less, with less variance even. The average is 0.29 GB out of 2GB, leaving a lot of room not only for growth, but for MySQL to cache as much of its tables in memory as well.
As you can see, this is far better resource utilization than without an op-code cache.
A nice summary for the entire week with regards to CPU utilziation can be seen in the following graph.
Note that Monday and Tuesday were without any op-code cache, Wednesday was with APC (3.0.13) starting at midnight, and Thursday and Friday are with eAccelerator. Note the hight of the Mon/Tue peaks vs. the mere hills on Thu/Fri.
Note: Ignore the red and magenta parts in the graph, since this was one off non-web load ran with the "nice" command.
Drawbacks of PHP op-code caches: Segmentation Faults
One common drawback of most op-code caches is that they often cause the web server to crash by causing a segmentation fault. From that point on, one Apache process is unavailable. This causes either an error 500 (server error) or the dreaded blank pages (White Screen of Death).
When this happens, you will see a message like this in Apache's error log:
[Fri Mar 02 03:55:04 2007] [notice] child pid 30253 exit signal Segmentation fault (11)
[Fri Mar 02 03:55:04 2007] [notice] child pid 30256 exit signal Segmentation fault (11)
[Fri Mar 02 03:55:04 2007] [notice] child pid 30257 exit signal Segmentation fault (11)
[Fri Mar 02 03:55:04 2007] [notice] child pid 30393 exit signal Segmentation fault (11)
The down blip above in the last memory graph was due to such a case with eAccelerator crashing Apache.
The only remedy is to restart the web server at this point.
In order to avoid downtime, there are solution out there that detect this condition, and automatically restart Apache when this happens. One such solution is the logwatcher script. This causes about one minute of downtime. Depending on the nature of your site, this may or may not be an acceptable solution.
Which one to choose: APC or eAccelerator or XCache?
As one blogger puts it: choose your poison!
The choice of which cache to use depends on several factors. All of them do the job fairly well. The difference in speed is not very noticeable.
Empirical observations on the above site show that while APC makes it feel that it has less page execution times, although a controlled benchmark failed to confirm this.
The graphs above show that eAccelerator provides better CPU and memory savings. As for memory, eAccelerator uses about 5 MB less of memory per Apache process than does APC, which can add up to significant savings.
A benchmark of Drupal with PHP APC vs. eAccelerator was conducted by 2bits. It includes Drupal 5.1, as well as the current HEAD with some menu system enhancements, and tests Drupal without any op-code caches/accelerators, with APC, and with eAccelerator. This is not a live site, but a test environment.
Other points to consider:
- APC is maintained by core PHP developers, including Rasmus and others. APC does not utilze a disk cache, unlike both eAccelerator and Xcache (although it is configurable).
- XCache is fairly new, although it seems to have momentum behind it.
- All of them suffer from the above drawback of segmentation faults.
For a large site receiving tens of thousands of page views per day or more, a PHP op-code cache is a must. Which one to use is not an easy question to answer, but they are pretty similar. Segmentation faults is the plague of all of them as well, but possible workarounds are available.
These are links and articles on PHP op-code caches/accelerators. This page focuses on free op-code caches. There are some commerical closed source ones out there.
- APC: Alternative PHP Cache. A free op code cache maintained by PHP code developers.
- My article on Installing PHP APC on Ubuntu/Debian. Applies to Dapper as well as Edgy.
- eAccelerator, a free fork of the now abandoned Turck MMCache.
- XCache. A free project by lighttpd.
- Drupal.org page on PHP caches.
- Article at DevBee on eAccelerator.
- IBM developerWorks on XCache.
- Oracle article by Ilia Alshanetsky on accelerating PHP code performance, with a section on op-code caches.
- Blog post on APC, eAccelerator and XCache.
- Benchmarking APC and eAccelerator.
- PHP Accelerators.
- Debian/Ubuntu packages for APC and eAccelerator. Not up to date but may prove useful for some.