Drupal HTTP Cache
Drupal doesn't support HTTP caching out of the box like Plone, but it can be extended for this, using a small patch and some Apache2.2 configuration.
Apache 2.2 Configuration
First, the apache configuration file httpd.conf needs to be configured to allow HTTP caching via mod_cache and mod_disk_cache.
# configure disk caching directory CacheRoot /var/cache/apache2/mod_disk_cache/WEBSITENAME # enable caching for topmost URLs CacheEnable disk / # disable caching for some sub URLs CacheDisable /pipermail
Drupal-5.3 Modifications
Second, the attached diff /exchange/httpcache-5.3.diff needs to be applied, it changes a couple things:
-
Allow specification of
anon_http_cache_secondsin the config section ofdrupal-5.3/sites/default/settings.php. A value >0 causes anonymously accessed pages to be HTTP-cached for this number of seconds. -
The logic in
drupal-5.3/includes/bootstrap.incis adapted to avoid always forcing html page expiration and allow HTTP caching for anon_http_cache_seconds seconds. -
A rewrite rule is added to
drupal-5.3/.htaccessto allow caching of the Drupal root URL. -
Also,
bootstrap.incis adapted to avoid caching if theX-Script-Chrome:header is specified, this is needed in case a theme is used that changes look in correspondence to this header.
Benchmarking
To verify the usefulness and quantify the gain of the above caching setup, the Apache Benchmarking Tool can be used, for example like this:
ab -n 100 http://testbit.eu/book/Rapicorn-Tutorial
The first benchmark is executed with Drupal caching completely turned off (adjustable under drupal-5.3/admin/settings/performance). This means that each page is rerendered completely in PHP:
# Caching-mode:Disabled Aggregate-and-compress-CSS-files:Disabled Time taken for tests: 81.608534 seconds Complete requests: 100 Total transferred: 843900 bytes HTML transferred: 780800 bytes Requests per second: 1.23 [#/sec] (mean) Time per request: 816.085 [ms] (mean) Transfer rate: 10.10 [Kbytes/sec] received
Then with normal Drupal caching enabled, cached pages are delivered from a page-cache MySQL-DB table with very little PHP code executed:
# Caching-mode:Normal Aggregate-and-compress-CSS-files:Enabled Time taken for tests: 8.862656 seconds Complete requests: 100 Total transferred: 767100 bytes HTML transferred: 706200 bytes Requests per second: 11.28 [#/sec] (mean) Time per request: 88.627 [ms] (mean) Transfer rate: 84.51 [Kbytes/sec] received
Page delivery is roughly 9 times faster now.
Finally, the HTTP cache is enabled e.g. by a value like anon_http_cache_seconds = 60 in settings.php and by CacheEnable in the Apache configuration:
# Caching-mode:Normal Aggregate-and-compress-CSS-files:Enabled CacheEnable-disk-/ Time taken for tests: 0.264496 seconds Complete requests: 100 Total transferred: 769600 bytes HTML transferred: 707900 bytes Requests per second: 378.08 [#/sec] (mean) Time per request: 2.645 [ms] (mean) Transfer rate: 2839.36 [Kbytes/sec] received
With Apache handling the majority of page deliveries now, delivery is sped up by a factor of 300, compared to the cacheless setup (and still 33 times faster than with normal Drupal caching).
Side Effects
It should be noted that Drupal modules (or PHP code in general) that takes action upon equal anonymous page requests will be called less often with activated HTTP caching. That is because Drupal isn't even activated when cached pages can be served by Apache. In practice, no significant problems are expected from active HTTP caching, but for examples page counters can be too small by an order of magnitude. If accurate page access numbers are needed, they should be generated from statistics extraction from Apache's log files (cached page delivery is still regularly logged by Apache).
| Attachment | Size |
|---|---|
| httpcache-5.3.diff | 4.53 KB |

Drupal.org submission
Submission of this page and the patch to drupal.org against drupal-5.3 is pending. I'd like to work out the caching details here first and provide solid documentation with regards to the effects.