【问题标题】:How to clear APC cache entries?如何清除 APC 缓存条目?
【发布时间】:2010-10-29 00:15:14
【问题描述】:

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

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

【问题讨论】:

  • 我对如何清除过期条目感兴趣!您可以指定一个 ttl,但 php.net 文档说它会在下一个请求过期时被删除...

标签: php performance caching apc


【解决方案1】:

您可以使用PHP函数apc_clear_cache

调用apc_clear_cache()会清空系统缓存,调用apc_clear_cache('user')会清空用户缓存。

【讨论】:

  • 我发现要通过命令行执行此操作,您需要进入 apc.ini 并设置:apc.enable_cli=1
  • lo_fye:这真的有效吗?根据我的经验,我发现 APC CLI 与 apache 的 APC 缓存完全分离——这是正确的,因为任何 CLI 进程都在与 Apache 完全分离的进程中运行。
  • Frank Farmer:我确认这确实适用于运行 PHP 5.3.10 和 PHP-FPM 接口的 Apache 或 Nginx。我创建了一个执行此命令的 shell 脚本php -r "apc_clear_cache();"
  • 如果您使用 mod_php 运行 PHP,这将不起作用。出于弗兰克法默所说的原因。
  • 我用 Nginx 运行 Ubuntu Server 12.04,用 PHP 5.4 运行 PHP-FPM。命令行上的 apc_clear_cache() 和 apc_clear_cache('user') 不会清除网络服务器/网页的 APC 缓存!!!
【解决方案2】:

这在文档中没有说明,但是要清除操作码缓存,您必须这样做:

apc_clear_cache('opcode');

编辑:这似乎只适用于一些旧版本的 APC..

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

【讨论】:

  • 我应该补充一点,如果你正在运行 mod_php 并想通过 cli-mode php 清除缓存,你不能真正做到这一点,因为两者运行在不同的环境中。我的解决方案是让 cli 模式 php 使用 file_get_contents 通过 http 调用自身。丑陋,但它有效。
  • 使用 netcat 将有效 fastcgi 请求的转储直接通过管道传输到 php-fpm 无需安装真正的 http 服务器,因为 php-fpm 服务器可能与 http 服务器分开跨度>
  • 这个答案是错误的。就像文档中解释的那样,如果给定的参数是 != 'user',则操作码缓存总是被清除。
  • @naitsirch 也许这是在最新版本中修复的错误。在我发布答案时,这对我有用。不幸的是,我不知道我当时使用的是什么版本,但这个答案显然对其他 25 个表面上使用与我相同的版本的人有用。文档并不总是正确的,对于旧版本也绝对不正确。
【解决方案3】:

我们在 APC 和指向文件的符号链接的符号链接方面遇到了问题——它似乎忽略了文件本身的变化。不知何故,对文件本身进行触摸有所帮助。我不知道修改文件和触摸它有什么区别,但不知何故这是必要的......

【讨论】:

    【解决方案4】:

    我认为这些答案中的任何一个都不能真正用于从命令行清除 APC 缓存。正如上面Frank Farmer 所评论的,CLI 在与 Apache 不同的进程中运行。

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

    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']);
      

    【讨论】:

    • 你也可以只重启服务器,例如如果您使用的是 mod_php,则为 Apache;如果您正在使用,则为 PHP FPM。您的解决方案更优雅(无需重新启动服务器)但更复杂:)
    • 这比重新启动 php-fpm/apache 更好,因为它不需要您的部署用户具有 sudo 访问权限。如果您要部署到多台服务器,为每台服务器输入 sudo 密码可能会很麻烦。
    • 我个人不介意输入 sudo 密码(我的部署脚本保存了密码)。但我想尽可能避免停机,这就是我对刷新 APC 文件感兴趣的原因。对于 Nginx,有一种(不那么简单的)重启方式,无需停机。我不知道 PGPfcgi,但我不这么认为。冲洗 APC 会导致停机吗?
    • @andrew 您可以将用户配置为使用 sudo 而无需输入密码。不过,如果只需要清除 APC,那确实更好,就像 Julien 说的那样。
    • @Julien 我想如果您存储 cpu 密集型结果或其他东西,它可能会增加服务器负载。我不会在高峰时段这样做。
    【解决方案5】:

    我知道这并不适合所有人,但是:为什么不优雅地重启 Apache?

    例如如果是 Centos/RedHat Linux:

    sudo service httpd graceful
    

    Ubuntu:

    sudo service apache2 graceful
    

    【讨论】:

    • 我知道这并不理想,但我很高兴你提到这个是一个快速而肮脏的解决方案。
    • 很抱歉重新打开此线程,但我遇到了同样的问题,我想知道为什么 cronjob 不能使优雅的 apache2 重新启动成为理想的选择?这种方法有哪些缺点?
    • @user2028856 它没有任何问题,只是有些人可能并不总是完全控制服务器。因此,如果它对您有用 - 请使用它。
    • @TadasSasnauskas “并不总是完全控制服务器”是什么意思?我的意思是每半小时左右运行一次会导致 apache 崩溃或破坏其他一些正在运行的操作,例如 cron 备份?
    • @user2028856 我的意思是有些人可能会将他们的网站托管在共享服务器上,而无法重新启动 Web 服务器。考虑到您不通过启用 apc 的 cli 运行后台工作程序,每 30 分钟运行一次正常重启应该没问题(长话短说:在某些情况下会导致内核崩溃)
    【解决方案6】:

    创建 APC.php 文件

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

    从浏览器运行它。

    【讨论】:

    • 据我了解,CLI 实例不会共享同一个 APC 缓存内存段,所以这只会清除一个空的、隔离的 APC 缓存段。
    • 根据发行版和配置,APC 缓存可能有单独的内存段,我已对其进行更新以获得更通用的解决方案。
    【解决方案7】:

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

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

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

    这仅适用于用户缓存。

    【讨论】:

      【解决方案8】:

      另一种尚未提及的命令行使用可能性是使用 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 调用它。

      【讨论】:

        【解决方案9】:

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

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

        【讨论】:

        • service php5-fpm reload 是什么让它工作我检查了 apc.php 状态文件并重置了缓存状态我在将选项 apc.stat=0 添加到 php.ini 后需要这个
        【解决方案10】:

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

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

        【讨论】:

        • 你从哪里得到这个页面?
        • @Pacerier 如果您的系统中安装了php-apc 软件包,您将获得此界面。
        【解决方案11】:

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

        APCu

        php -r "apcu_clear_cache();" 
        

        APC

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

        【讨论】:

        • 我的终端出现这样的错误,请帮助我“PHP 致命错误:在第 1 行的命令行代码中调用未定义的函数 apc_clear_cache()”
        • 你应该用“php -m | grep apc”测试你的apc是否正确安装
        【解决方案12】:

        apc.ini

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

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

        【讨论】:

          【解决方案13】:

          如果你在ubuntu下运行fpm,需要运行下面的代码(勾选12和14)

          service php5-fpm reload
          

          【讨论】:

            【解决方案14】:

            新的 APC 管理界面具有添加/清除用户缓存和操作码缓存的选项,一个有趣的功能是从操作码缓存添加/刷新/删除目录

            APC Admin Documentation

            【讨论】:

              【解决方案15】:

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

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

              它也适用于 opcache。

              在这里查看它的工作原理:http://gordalina.github.io/cachetool/

              【讨论】:

                【解决方案16】:

                如 APC 文档中所定义:

                清除缓存运行:

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

                【讨论】:

                  【解决方案17】:

                  如果你想通过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、token...)

                  【讨论】:

                    【解决方案18】:

                    我为 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 步。 运行应用程序。

                    【讨论】:

                      【解决方案19】:

                      TL;DR:删除/storage/framework/cache/data/处的缓存文件

                      我启用了 APC,但它没有安装(也无法安装),所以它抛出了Call to undefined function Illuminate\Cache\apc_store()

                      “好的,我只是禁用它,它应该可以工作”。

                      嗯,不。然后我被Call to undefined function Illuminate\Cache\apc_delete()卡住了

                      【讨论】:

                        猜你喜欢
                        • 2014-02-04
                        • 2012-02-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2011-01-14
                        • 2014-02-10
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多