From Cerb Wiki
Jump to: navigation, search

Alternative PHP Cache (APC)

APC Flowchart

When a web server receives an HTTP request for a PHP script the human-readable source code is compiled into a machine-friendly format called "opcodes". By default, the opcodes are only kept around long enough to serve an individual request and then they're disposed of to free up resources.

The default behavior makes sense in a shared hosting environment where dozens of scripts and applications may be sharing the same system resources. However, as you can imagine, when a single PHP webapp receives a disproportionately large amount of the traffic then the process of constantly re-parsing its source code can become a performance bottleneck.

The Alternative PHP Cache (APC) is an extension for PHP which caches the most frequently-accessed scripts in their machine-friendly opcode format. Typically, APC is a moderate, turnkey performance-boost that doesn't require any application-level changes to benefit from the cache.

Installing APC

Installing APC is an advanced topic. If you don't have administrator-level control of your server then it's not likely to be something you're able to do.

Like most PHP extensions, APC is installed through the PECL repository. Installation instructions will vary according to your operating system and distribution. Check your package manager for the appropriate package for PHP's PEAR commands. For example, with Debian Etch Linux you want the php-pear package.

You can search for platform-specific instructions.

Once PECL is installed, you can issue the following console command (you may need to use sudo or your root account): <geshi lang="bash"> pecl install apc </geshi>

Then add the following to your php.ini or apc.ini: <geshi lang="ini">

  1. configuration for php APC module

[apc] apc.cache_by_default=0 # disable by default apc.shm_segments=1 apc.shm_size=256 # megabytes </geshi>

To enable APC on a site-by-site basis with Apache, set the following option in the site's vhost.conf or .htaccess file: <geshi lang="apache"> php_flag apc.cache_by_default On </geshi>


APC usually comes with a script (somewhere like /usr/share/php/apc.php) that you can copy into your web-path for monitoring and tuning. That's usually the best way to confirm everything is working as expected.


Memcached flowchart

In web applications the majority of the latency in serving a request is caused by interactions with a database. Databases are often necessary for managing persistence and to providing a way to sort and filter large collections of information. However, databases are also overused to frequently read and write infrequently-changed information -- or worse, information that never changes.

Memcached provides a shared memory cache where arbitrary information can be read frequently without incurring the overhead of a database.

Memcached advantages:

  • Shared memory allows multiple processes to share a single cache.
  • Cache requests can be distributed over multiple instances.
  • It's volatile memory and shouldn't be used to store anything that you can't repopulate from a persistent source (like the filesystem or a database).

Memcached disadvantages:

  • Applications need to be designed with memcached support in mind.
  • It's yet another process running on your server.
  • It provides no means of authentication. That's up to you.

Installing Memcached

It's often best to install Memcached from your platform's package manager; however, some distributions (such as Debian Etch) will install rather old versions. You want version 1.2.2 or later.

You'll also use PECL to install PHP's Memcached extension. This API is used by Cerb4 when Memcached support is enabled..

Once Memcached is installed, you need to edit your Cerb4 framework.config.php file and change the following lines: <php> //define('DEVBLOCKS_CACHE_PREFIX',); // ONLY A-Z, a-z, 0-9 and underscore //define('DEVBLOCKS_MEMCACHED_SERVERS',''); </php>

To something like: <php> define('DEVBLOCKS_CACHE_PREFIX','myhelpdesk'); // ONLY A-Z, a-z, 0-9 and underscore define('DEVBLOCKS_MEMCACHED_SERVERS',''); </php>

DEVBLOCKS_CACHE_PREFIX - This prefix allows multiple applications (e.g. helpdesk instances) to share Memcached. If no prefix is used, then only one application can use a particular key (e.g. "worker_list"). The prefix can be anything as long as it's unique. We often suggest using the database name as the prefix.

DEVBLOCKS_MEMCACHED_SERVERS - This is a list of Memcached instances to distribute requests between. Usually you won't need more than a single Memcached instance, but if you want to distribute requests then add more host:port pairs delimited by commas (e.g. ",").

Security Implications

Memcached is well worth the following hassle, but make sure you understand the security implications.

By default, Memcached does not have any form of authentication. Make sure you don't bind Memcached to a publicly-accessible network interface without establishing firewall rules. It defaults to only serving local requests on the address.

You also need to consider if other local users and scripts can connect to Memcached's port (11211 by default). Choosing a unique prefix will help safeguard your cached data, but it shouldn't be all you rely on.

In summary:

  • Don't bind Memcached to a public network interface without firewall rules.
  • Consider that local users can connect to Memcached's port. Choosing a non-standard port is a decent start, but local users with shell access can easily discover running services with commands like:
netstat --tcp -l
  • If you don't set a prefix for Memcached keys then anyone connecting to the port can read your cached information if they're familiar with an application's source code (and Cerb4 comes with the full source code readable).


You can test that Memcached is installed by using telnet (telnet localhost 11211) to connect to the proper port. Type version and hit enter. Then type quit and hit enter.

To make sure Cerb4 is using Memcached and not the default disk-based cache, you can delete the /cerb4/libs/devblocks/tmp/zend_cache* files and reload a page in the helpdesk. The zend_cache* files shouldn't be recreated if Memcached is working properly.