Is APC opcode cache shared between PHP-FPM pools/workers?

16.2k views Asked by At

Internet has a lot of discussions that calling apc_cache_clear() in CLI does not clear opcode caches from "web" PHP processes, whether they are run inside Apache or by FPM (see How to clear APC cache entries? ). As a suggested solution, it's possible to create a simple PHP page that calls apc_cache_clear(), and call that from CLI. Symfony's ApcBundle does that.

If the apc_cache_clear() from CLI does not empty the cache from Apache/FPM, does it between FPM workers? If I call /clear_apc_cache.php over HTTP, it's run by only by one of the FPM worker processes. So, is the APC opcode cache really shared between pools and workers - and more specific: is it cleared from all workers automatically?

3

There are 3 answers

12
Herman J. Radtke III On BEST ANSWER

All the php-fpm workers share the same opcode cache as the parent php-fpm process; source. If you have a /apc_clear_cache.php file and you call that over HTTP (using something like curl), you will clear the opcode cache for all workers using the same php-fpm master process.

This blog article has a very good explanation of how apc works and how to clear it effectively during release.

1
Tero Kilkanen On

I have just found out that different pools also share the same APC cache, at least in PHP 5.4 with FPM and as far as the opcode cache content is concerned.

This is how I noticed it:

I have set up multiple PHP-FPM pools, where each pool is chrooted under /srv/www/domain.com/ directory.

The main location for PHP scripts is /srv/www/domain.com/docroot/.

Now, if I create a file /srv/www/domain_1.com/docroot/test.php, and load the script, it shows what it should show.

However, when I create the file /srv/www/domain_2.com/docroot/test.php, the contents show also up under domain_1.com.

I think this happens because APC uses the file location as the key for its cache, and in both cases the key is /docroot/test.php.

Clearing the opcode cache might be restricted only to a single pool. I haven't tested this though.

EDIT Clearing the opcode cache isn't restircted to a single app pool, the complete APC cache is cleared when apc_cache_clear() is called.

I also tried to use apc.mmap_file_mask to specify a different mask for every pool. This didn't change anything, updates in one app pool files were seen in other pools.

This behaviour was observed with apc.stat=0 setting. All changes to files are monitored with lsyncd, forcing a recompile of the entry in APC cache.

  • Tero
4
Stuart Carnie On

You can clear the opcode cache via the cli without having to deploy the files to your website if you execute the script via the FastCGI interface directly.

I've created this gist which you can use on your servers to clear the php5-fpm cache.

If you're using unix sockets:

php clear-apc.php --sock /var/run/php5-fpm.sock

Otherwise:

php clear-apc.php --port=[port]

or omit for default 127.0.0.1:9000