如何清除APC缓存条目?


170

部署网站的新版本时,我需要清除所有APC缓存条目。APC.php有一个用于清除所有操作码缓存的按钮,但是我看不到用于清除所有用户条目,所有系统条目或所有按目录条目的按钮。

是否可以通过命令行或其他方式清除所有缓存条目?


1
我会对如何清除过期的条目感兴趣!您可以指定一个ttl,但是php.net doc说它在下一个请求过期时就被删除了……
Surrican 2010年

Answers:


145

您可以使用PHP函数apc_clear_cache

调用apc_clear_cache()将清除系统缓存,而调用apc_clear_cache('user')将清除用户缓存。


20
我发现要通过命令行执行此操作,您需要进入apc.ini并设置:apc.enable_cli = 1
lo_fye

51
lo_fye:这真的有效吗?以我的经验,我发现APC CLI与apache的APC缓存是完全分开的-的确如此,因为任何CLI进程都在与Apache完全独立的进程中运行。
Frank Farmer

9
弗兰克·法默:我确认这对运行PHP 5.3.10和PHP-FPM接口的Apache或Nginx都适用。我创建了一个执行该命令的shell脚本php -r "apc_clear_cache();"
ezraspectre 2012年

13
如果您使用mod_php运行PHP,这将不起作用。由于这个原因,弗兰克·法默说。
大卫

11
我在Nginx上运行Ubuntu Server 12.04,在PHP 5.4上运行PHP-FPM。命令行上的apc_clear_cache()和apc_clear_cache('user')不会清除Web服务器/网页的APC缓存!
Pieter Vogelaar,

117

我认为这些答案都无法真正从命令行清除APC缓存。如上文的Frank Farmer所述,CLI在与Apache分开的进程中运行。

我从命令行清除的解决方案是编写一个脚本,该脚本将APC清除脚本复制到web目录中并对其进行访问,然后将其删除。该脚本仅限于从本地主机访问。

  1. apc_clear.php

    这是脚本复制到Web目录,访问和删除的文件。

    <?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');
    }
  2. 缓存清除脚本

    该脚本将apc_clear.php复制到Web目录,对其进行访问,然后将其删除。这基于Symfony任务。在Symfony版本中,将调用复制和取消链接的Symfony形式,以处理错误。您可能想要添加检查成功的检查。

    copy($apcPaths['data'], $apcPaths['web']); //'data' is a non web accessable directory
    
    $url = 'http://localhost/apc_clear.php'; //use domain name as necessary
    $result = json_decode(file_get_contents($url));
    
    if (isset($result['success']) && $result['success'])
    {
      //handle success
    }
    else
    {
      //handle failure
    }
    
    unlink($apcPaths['web']);

8
您也可以重新启动服务器,例如,如果使用的是mod_php,则重新启动服务器;如果使用的是PHP FPM,则重新启动服务器。您的解决方案更优雅(无需重新启动服务器),但更复杂:)
El

5
这比重新启动php-fpm / apache更好,因为它不需要您的部署用户具有sudo访问权限。如果要部署到多个服务器,则为每个服务器输入sudo密码可能会很麻烦。
安德鲁(Andrew)2012年

我个人不介意输入sudo密码(我的部署脚本保存密码)。但是我想尽可能避免停机,这就是为什么我对刷新APC文件感兴趣。对于Nginx,有一种(不太容易)的重启方式而不会造成任何停机。我不知道PGPfcgi,但我不这么认为。冲洗APC是否会导致停机?
朱利安

@andrew您可以配置用户使用sudo而不输入密码。尽管只需清除APC,但这确实更好,就像朱利安所说。
ChocoDeveloper

1
@Julien我想如果您存储CPU密集型结果或其他内容,可能会增加服务器负载。在高峰时段我不会这样做。
ChocoDeveloper

68

我知道不是每个人都可以,但是:为什么不进行优雅的Apache重新启动?

例如,对于Centos / RedHat Linux:

sudo service httpd graceful

Ubuntu:

sudo service apache2 graceful

4
我知道这不是理想的选择,但很高兴您提到此内容,以寻求快速而又肮脏的解决方案。
布莱恩·佩蒂

1
抱歉,重新打开此线程,但我遇到了同样的问题,我想知道为什么cronjob无法使优美的apache2重新启动理想?这种方法有哪些缺点?
user2028856

@ user2028856它没有任何问题,只是有些可能并不总是完全控制服务器。因此,如果适合您,请使用它。
Tadas Sasnauskas 2014年

@TadasSasnauskas“不总是完全控制服务器”是什么意思?我的意思是每半小时左右运行一次会导致apache崩溃或破坏其他一些正在运行的动作,例如cron备份吗?
user2028856

@ user2028856我的意思是有些人可能将其站点托管在共享服务器上,而无法重启Web服务器。假设您没有通过启用
APC的

29

文档中未对此进行说明,但是要清除操作码缓存,您必须执行以下操作:

apc_clear_cache('opcode');

编辑:这似乎仅适用于APC的某些旧版本。

无论您使用的是哪个版本,都无法从php cli脚本中清除mod_php或fastcgi APC缓存,因为cli脚本将以与mod_php或fastcgi不同的进程运行。您必须在要为其清除缓存的进程(或子进程)中调用apc_clear_cache()。使用curl运行简单的php脚本就是这样一种方法。


1
我应该补充一点,如果您正在运行mod_php并想通过cli-mode php清除缓存,您将无法真正做到这一点,因为两者都在不同的环境中运行。我的解决方案是使用file_get_contents通过cli模式在php上调用自身。丑陋,但是行得通。
ColinM 2010年

Pipe'ing有效的FastCGI的请求,直接到PHP-FPM与netcat的作品的转储,而无需安装一个真正的http服务器,因为PHP-FPM服务器可以从HTTP一个独立的
baloo

这个答案是错误的。如文档中所解释的,如果给定参数为!='user',则始终清除操作码缓存。
naitsirch

@naitsirch也许这是最新版本中已修复的错误。在我发布答案时,这对我有用。不幸的是,我当时不知道使用的是哪个版本,但是对于其他25个表面上使用与我使用的相同版本的人来说,此答案显然有用。
ColinM 2013年

12

如果要在命令:中清除apc缓存(如果需要,请使用sudo)

铜铜合金

php -r "apcu_clear_cache();" 

装甲运兵车

php -r "apc_clear_cache(); apc_clear_cache('user'); apc_clear_cache('opcode');"

我在这样的终端上遇到错误,请帮我“ PHP致命错误:在第1行的命令行代码中调用未定义的函数apc_clear_cache()”
RaviPatidar 2015年

1
|您应该测试您的APC的正确和“grep APC PHP -m”安装
莱奥Benoist

9

如果您在NGINX / PHP-FPM堆栈上运行,则最好的选择是重新加载php-fpm

service php-fpm reload (或者您的系统上可能有任何重新加载命令)


服务php5-fpm重新加载是使其工作的原因我检查了apc.php状态文件并重置了缓存状态在将选项apc.stat = 0添加到php.ini之后,我需要这个
塞勒姆

5

根据APC文档中的定义:

要清除缓存运行:

php -r 'function_exists("apc_clear_cache") ? apc_clear_cache() : null;'

4

尚未提及的命令行用法的另一种可能性是使用curl。

如果您使用库存的apc.php脚本,这不能解决所有缓存条目的问题,但是它可以调用已改编的脚本或您已放置的另一个脚本。

这将清除操作码缓存:

curl --user apc:$PASSWORD "http://www.example.com/apc.php?CC=1&OB=1&`date +%s`"

将OB参数更改为3,以清除用户缓存:

curl --user apc:$PASSWORD "http://www.example.com/apc.php?CC=1&OB=3&`date +%s`"

将这两行都放在脚本中,然后在您的环境中用$ PASSWORD调用它。


4

如果要通过json监视结果,可以使用以下脚本:

<?php

$result1 = apc_clear_cache();
$result2 = apc_clear_cache('user');
$result3 = apc_clear_cache('opcode');
$infos = apc_cache_info();
$infos['apc_clear_cache'] = $result1;
$infos["apc_clear_cache('user')"] = $result2;
$infos["apc_clear_cache('opcode')"] = $result3;
$infos["success"] = $result1 && $result2 && $result3;
header('Content-type: application/json');
echo json_encode($infos);

如其他答案中所述,必须通过http或curl调用此脚本,并且如果该脚本暴露在应用程序的Web根目录中,则必须加以保护。(通过ip,令牌...)


3

apc_clear_cache()仅适用于您希望清除缓存的同一PHP SAPI。如果您具有PHP-FPM并希望清除apc缓存,则必须通过其中一个php脚本(而不是命令行)来执行,因为这两个缓存是分开的。

我写了CacheTool,它是一个命令行工具,可以完全解决此问题,并且可以使用一个命令从命令行清除PHP-FPM APC缓存(它会为您连接到php-fpm并执行apc函数)

它也适用于opcache。

在这里查看其工作方式:http : //gordalina.github.io/cachetool/


2

APC的稳定器可以选择清除其接口本身中的缓存。要清除这些条目,您必须登录到apc界面。

APC可以选择在apc.php文件中设置用户名和密码。

在此处输入图片说明


您从哪里获得此页面?
Pacerier's

@Pacerier如果php-apc系统中已安装软件包,则将获得此界面。
陌生人

2

如果您在ubuntu下运行fpm,则需要运行以下代码(已在12和14上选中)

service php5-fpm reload

1

apc.ini

apc.stat =“ 1”将强制APC对每个请求的脚本进行统计(检查)以确定脚本是否已被修改。如果已被修改,它将重新编译并缓存新版本。

如果禁用此设置,则APC将不会检查,这通常意味着要强制APC重新检查文件,必须重新启动Web服务器或必须手动清除缓存。请注意,FastCGI Web服务器配置可能不会在重新启动时清除缓存。在脚本文件很少更改的生产服务器上,通过禁用统计信息可以显着提高性能。



0

对我来说,一个好的解决方案是在部署后根本不再使用过时的用户缓存。

如果在每个键上添加前缀,则可以在更改缓存条目的数据结构时更改前缀。这将帮助您在部署时获得以下行为:

  1. 仅部署更新后的结构后不要使用过时的缓存条目
  2. 不要在部署时清理整个缓存,以免降低页面速度
  3. 恢复部署后,某些旧的缓存条目可以重用(如果尚未自动删除条目)
  4. APC将在过期后删除旧的缓存条目,或者在丢失的缓存空间上删除

这仅适用于用户缓存。


0

创建APC.php文件

foreach(array('user','opcode','') as $v ){
    apc_clear_cache($v);
}

从浏览器运行它。


2
据我了解,CLI实例将不会共享相同的APC缓存内存段,因此除了清除一个空的,隔离的APC缓存段之外,它什么都不会做。
AB Carroll

根据发行版和配置,APC缓存可能具有单独的内存段,我对其进行了更新以获取更通用的解决方案。
anshuman 2013年

0

我的Symfony构建的解决方法是在同一台服务器上有很多实例:

步骤1. 创建触发器或设置文件标志的内容(例如Symfony命令),然后创建marker file..

file_put_contents('clearAPCU','yes sir i can buggy')

步骤2. 在开始的索引文件上,添加清除代码并删除marker file

if(file_exists('clearAPCU')){
    apcu_clear_cache();
    unlink('clearAPCU');
}

第2步。 运行应用程序。


-1

我们在APC和符号链接到文件的符号链接方面遇到了问题-似乎忽略了文件本身的更改。以某种方式对文件本身进行触摸很有帮助。我无法告诉您修改文件和触摸文件之间有什么区别,但是某种程度上是有必要的...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.