PHP op-code caches / accelerators: Drupal large site case study
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:
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:
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:
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.
Is your Drupal site slow?