Jul 142012
 

If you are a system administrator and you want to push the performance of your PHP website such as Drupal, WordPress or wrote by you or other programmers, there are good chances that you’ve heard about the Alternate PHP Cache or simply APC.

The Alternative PHP Cache (APC) is a free and open opcode cache for PHP. Its goal is to provide a free, open, and robust framework for caching and optimizing PHP intermediate code.

That everything you’ll read about APC on the php.net site, and i think is not enough in comparison to the huge boost of performance that this small component can give you, for some quick facts check the tests done by Guillermo Garron on his website.



How APC works

The first thing you need to know, is how a PHP program is run by the Zend Engine, these are steps to go from your PHP script to the code really used by the Engine, this is commonly known as “opcodes”, representing the function of the code.

  1. The first step is reading the PHP code from the filesystem and put it into memory.
  2. Lexing : The php code inside is converted into tokens or Lexicons.
  3. Parsing : During this stage, tokens are processed to derive at meaningful expressions.
  4. Compiling : The derived expressions are compiled into opcodes.
  5. Executing : Opcodes are executed to get the final result.

The goal of APC is bypass the steps from 1 to 4, caching in a shared memory segment the opcodes generated and then copies them into the execution process so Zend can actually execute the opcodes.

From lampzone.wordpress.com

Here are the detailed steps of what APC really does

1. During module init time ( MINIT), APC uses mmap to map file into shared memory.

2. During request time, APC replaces zend_compile_file() with its own my_compile_file().

What does my_compile_file do ?

1. If APC couldn’t find file in the cache, APC will call zend_compile_file to compile file

2. Get returned opcodes and store them into shared memory which read/write from different Apache child processes. ( We are talking about Apache prefork MPM here.)

3. Also store classes and function tables in shared memory.

4. Copy opcodes into Apache child process memory so Zend can execute the code.

So this is the theory, let’s see now how to install and configure it

APC installation

APC is a PHP extension so you have 2 ways to install it :

1) Install APC from a repository of your distribution.
I suggest to use this way whenever possible, keeping everything you have on your computer/server installed from a repository is a good practice that i always try to follow.

On Debian and Ubuntu APC is available on the main repository with this name:

root@xubuntu-home:~# apt-cache search apc php
php-apc - APC (Alternative PHP Cache) module for PHP 5

So you can install it with the command

sudo aptitude install php-apc

While if you use Red Hat Enterprise, Centos or Fedora you can use this command :

sudo yum install php-pecl-apc

2) The second way to install APC is with PECL, with this method you’ll download the last source and compile it for you computer.

On Debian and Ubuntu this should work (the name of the packages can change depending on your version of Ubuntu/Debian)

$ sudo apt-get install php-pear php5-dev apache2-threaded-dev build-essential
$ sudo pecl install apc

As told i suggest the method number 1, in the second you could have problem during the compilation and over time some updates could broke your local installation of APC.

APC Configuration

Once installed APC must be enabled in the configuration file of PHP: php.ini, if you have installed APC from a package this is already done and you just have to restart Apache (or FastCGI daemon like FPM) to see a new APC section in phpinfo() which will confirm it’s enabled.

Otherwise you have to include in your php.ini this line:

extension=apc.so

This is enough to have APC installed with all default parameters, but probably you want to change some of the default values.
Among the parameters there is apc.shm_size, which specifies how much memory to use for APC, the default is 30 MB, depending on your application and RAM on the server raise this number to 64, 128 or even 512 MB.

This is a suggested configuration for a box with 1Gb of RAM:

# cat /etc/php5/conf.d/apc.ini
extension=apc.so
apc.enabled=1
apc.shm_size=128
apc.cache_by_default="1"
apc.shm_segments="1"
apc.ttl="7200"
apc.user_ttl="7200"
apc.gc_ttl="1800"
apc.optimization = 0
apc.num_files_hint="1024"
apc.use_request_time = 1
apc.mmap_file_mask="/tmp/apc.XXXXXX"
apc.enable_cli="0"
apc.slam_defense="0"
apc.file_update_protection="2"
apc.max_file_size="1M"
apc.stat="1"
apc.write_lock="1"
apc.report_autofilter="0"
apc.include_once_override="0"
apc.rfc1867="0"
apc.rfc1867_prefix="upload_"
apc.rfc1867_name="APC_UPLOAD_PROGRESS"
apc.rfc1867_freq="0"
apc.localcache="0"
apc.localcache.size="512"
apc.coredump_unmap="0"

For a full explanation of these settings, refer to the online documentation.

APC includes a web page where you can see the usage of the cache, including fragmentation and other useful information. Copy the file apc.php (located in /usr/share/doc/php-apc/apc.php for Debian and Ubuntu) to your document root and point your browser to it to see a screen like this one:

apc.php

From here you can see the hits/misses % and an important statistic: Cache full count, this number tell how many time the cache has been completely filled, if this number goes up too quickly you probably have to raise the size of the cache.

One word of warning: If you don’t periodically restart Apache or PHP-FPM, your cache could become fragmented, as you’ll be able to see by visiting that web page. To avoid this, periodically empty the cache. I use a cron setting that once a day calls a web page on my site, which I call apc-clear.php, that empties the cache. It also checks that the address invoking it is local so it cannot be called from outside. Here is the content of apc-clear.php:

<?php
if (in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1')))
{
  apc_clear_cache();
  apc_clear_cache('user');
  apc_clear_cache('opcode');
  echo json_encode(array('success' => true));
}
else
{
  die('SUPER TOP SECRET');
}

And this is my cron:

0 6 * * * /usr/bin/curl --silent http://myserver.com/subdir/apc-clear.php

Conclusions

As you have seen in this article, setting up APC is really easy and will improves the throughput of your php pages many times, so why you should not use it ?

Popular Posts:

Flattr this!

  12 Responses to “Everything you need to know about APC (Alternate PHP cache)”

  1. Hi,
    I installed APC to server for my project but I have a problem about caching file. Server caching php files but after refresh on project page server caching same files again and reset the hit number of files.
    I didn’t solve this situation, what is the problem is there any missing configuration for APC?

    • Hello Mert,
      What the configuration of your APC ?
      In general the defaults are good enough once you have put the correct size of your APC cache.

  2. Okay, I just enabled APC Support. When I visit mydomain/info.php I can see that it is ENABLED. Do I have to do anything else? Do I have to incorporate any PHP code into my PHP files?

    Thank you!
    Richard

  3. Hi,

    Great post.

    However, and IMHO, you should call your php script from the command line rather than through curl, then the webserver. So you can get rid of the test on localhost.
    0 6 * * * /usr/bin/php /subdir/apc-clear.php

    And by the way, it seems important to me to specify that it’s a reasonably good practice to set apc.stat to 0 (Off) for a production server as it increase dramatically the performances of the caching (without forgetting a cache-clearing after an app update). It means that when a file is cached, apc doesn’t check every time if the file has changed before executing it, plus it’s better to avoid problem during the upload when you update your app for a busy site.

    Regards,

    • Thanks for the feedback,

      I’ve used curl mainly because APC it’s disabled for CLI on my setup, if it’s enabled in your you can probably use cron without any problem.

      Regarding apc.stat, all correct just remember that you’ll have to restart apache/php-fpm or clean the cache by hand any time you want to update your website.

  4. Hello!

    I tried to use your apc-clear.php, but is resulting in HTTP 500 Forbidden Error. Do you know what’s happened?

    Thanks a lot and congratulations for your article.

  5. I am using APC with Drupal 7 with the following configuration:
    apc.max_file_size=2M
    apc.ttl=7200
    apc.user_ttl=7200
    apc.gc_ttl=3600
    apc.shm_segments=1
    apc.shm_size=1028M
    apc.stat=0

    For the first 30 minutes after I restart Apache, the site works very good, but it gets slower gradually..I don`t know what I am missing.Any help would be appreciated..thanks

    • I suggest to enable the apc.php utility page on your webserver, in this way it will be easier for you to see at a glance if there are problems (fragmentation or full memory used)

  6. I am using APC with Magento. It uses the assigned memory untill it has used around 80%, then it stops caching new pages. Pages in cache are served fast, pages that aren’t in cache are slower and don’t get cahced anymore. It’s been tested with les memory configured in pac.shm.size, but the problem remains the same. Any ideas about what might be wrong?

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

*