15

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?

Community
  • 1
  • 1
Ville Mattila
  • 1,343
  • 3
  • 15
  • 28
  • 1
    As far as I understand FPM and APC, I believe they are shared. You basically have one instance of PHP running. Therefore, only one instance of APC. – nwalke Oct 18 '12 at 17:03
  • Thanks @tubaguy50035 for a comment. I think I need to do some more research to be sure... – Ville Mattila Oct 18 '12 at 18:46

3 Answers3

25

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.

larcher
  • 183
  • 2
  • 8
Herman J. Radtke III
  • 1,804
  • 1
  • 24
  • 29
  • Thanks for answering the question with good sources. This clarified my issue. =) – Ville Mattila Oct 21 '12 at 07:37
  • 1
    As written [above](http://stackoverflow.com/a/12981832/1447317) you should clear APC cache in context of HTTP request, however, it will clear cache for **all** pools, which are forked from same master process (this is typical for most distros). – boda2004 Nov 29 '12 at 09:19
  • 2
    I think the child processes are forked from the same master process even they're in different pools, so there's only one shared apc cache. One way to work around is to start different php-fpm master processes. – Jerry Mar 16 '13 at 17:40
  • @Jerry You are right! The realpath cache is local to the workers, not the apc cache. I will update my answer. – Herman J. Radtke III Mar 16 '13 at 20:49
  • 1
    @HermanJ.RadtkeIII Your answer still states "It is not shared between pools;" which is incorrect, as the above comments have stated, if the pools are from the same master PHP-FPM process the pools will share the opcode cache. Additionally, cache clearing is not limited to just that pool, it will clear the cache for all pools which come from the same parent PHP-FPM process. – Phizes May 19 '13 at 23:11
  • @Herman I believe you misread [source](http://news.php.net/php.internals/63539). It states that pools forked from the same parent process are able to share the opcode cache, this is exactly what happens. What the poster in the link was talking about was the possibility of sharing the opcode cache with pools forked from _different_ parent processes. I have had the issue with the opcode being shared between pools, and the common answer is to start multiple PHP-FPM master processes. [Example, and partial explanation](http://forum.nginx.org/read.php?3,122844) apc.php's file listing reveals it. – Phizes May 19 '13 at 23:11
  • This answer should state clearly that if the opcode cache is not shared between pools the statcache is shared between pools in processes and that this means pools using apc, for example, may have some file name conflicts. – regilero May 21 '13 at 10:35
  • @Phizes thank you for catching this. I updated the answer to make it clear that different php-fpm pools share an opcode cache. – Herman J. Radtke III May 21 '13 at 14:46
  • @regilero are you referring to the statcache for realpath? I think that is out of the scope of this question. The link I provided in my answer does speak to the statcache differnces though. – Herman J. Radtke III May 21 '13 at 14:47
  • @Herman J. Radtke III, yes, looking at misunderstanding in comments I think adding a clear note about that in the answer would made it a better one. Links provided are really good but explaining here that the opcode cache is not 'all' the apc cache and may explain shared-things-bugs would be nice. – regilero May 21 '13 at 15:45
  • @HermanJ.RadtkeIII - just wanted to inform you that the blog article is no longer available. – Con Antonakos Mar 03 '14 at 22:49
  • @ConAntonakos it looks like they changed the blog around. I fixed the link. Thank you! – Herman J. Radtke III Mar 04 '14 at 18:23
11

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

Stuart Carnie
  • 5,458
  • 1
  • 29
  • 27
3

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
Tero Kilkanen
  • 328
  • 1
  • 12
  • 1
    Kiitos Tero - as far as I've understood the [answer above](http://stackoverflow.com/a/12981832/769144), it seems that the opcode cache is owned the main process, so this behavior is kind of expected... except that definitely the whole source file path should be the key. I have to test this in my own setup too. – Ville Mattila Jan 21 '13 at 23:43