APC操作码缓存是否在PHP-FPM池/工作者之间共享?

时间:2012-10-12 13:46:48

标签: apc php opcode-cache

互联网有很多讨论,在CLI中调用apc_cache_clear()不会清除“web”PHP进程中的操作码缓存,无论它们是在Apache内部运行还是由FPM运行(参见How to clear APC cache entries?)。作为建议的解决方案,可以创建一个调用apc_cache_clear()的简单PHP页面,并从CLI调用它。 Symfony's ApcBundle就是这么做的。

如果来自CLI的apc_cache_clear()没有从Apache / FPM清空缓存,那么它是否在FPM工作者之间?如果我通过HTTP调用/clear_apc_cache.php,它只由一个FPM工作进程运行。那么,APC操作码缓存真正是否在池和工作人员之间共享 - 更具体:它是否会自动从所有工作人员中清除?

3 个答案:

答案 0 :(得分:23)

所有php-fpm工作者共享与父php-fpm进程相同的操作码缓存; source。如果你有一个/apc_clear_cache.php文件并且通过HTTP调用它(使用像curl这样的东西),你将使用相同的php-fpm主进程清除所有worker的操作码缓存。

这个blog article非常好地解释了apc如何工作以及如何在发布期间有效地清除它。

答案 1 :(得分:11)

如果直接通过FastCGI界面执行脚本,则可以通过cli清除操作码缓存,而无需将文件部署到您的网站。

我创建了this gist,您可以在服务器上使用它来清除php5-fpm缓存。

如果您使用的是unix套接字:

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

否则:

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

或省略默认127.0.0.1:9000

答案 2 :(得分:3)

我刚刚发现不同的池也共享相同的APC缓存,至少在PHP 5.4中使用FPM以及操作码缓存内容。

这是我注意到的:

我已经设置了多个PHP-FPM池,每个池都在/srv/www/domain.com/目录下chroot。

PHP脚本的主要位置是/srv/www/domain.com/docroot /.

现在,如果我创建一个文件/srv/www/domain_1.com/docroot/test.php,并加载脚本,它会显示它应该显示的内容。

但是,当我创建文件/srv/www/domain_2.com/docroot/test.php时,内容也显示在domain_1.com下。

我认为这是因为APC使用文件位置作为其缓存的密钥,在这两种情况下密钥都是/docroot/test.php。

清除操作码缓存可能仅限于单个池。我没有测试过这个。

编辑清除操作码缓存不会重新提交到单个应用程序池,调用apc_cache_clear()时会清除完整的APC缓存。

我还尝试使用apc.mmap_file_mask为每个池指定不同的掩码。这没有任何改变,一个应用程序池文件中的更新在其他池中可见。

使用apc.stat = 0设置时会观察到此行为。使用lsyncd监视对文件的所有更改,强制重新编译APC缓存中的条目。

  • 特罗