【问题标题】:Using PHP APC cache in CLI mode using dumpfiles使用转储文件在 CLI 模式下使用 PHP APC 缓存
【发布时间】:2012-04-19 05:42:29
【问题描述】:

我最近开始在我们的服务器上使用 APC 缓存。我们产品中最重要的部分之一是 CLI(Cron/scheduled)进程,其性能至关重要。通常,批处理作业包括并行运行大约 16-32 个进程大约一个小时(它们每隔几分钟“重新启动”一次)。

默认情况下,在 CLI 中使用 APC 缓存是浪费时间,因为在各个调用之间没有保留操作码缓存。但是APC还包含apc_bin_dumpfile()apc_load_dumpfile()函数。

我在想这两个函数可用于使 APC 在 CLI 模式下高效,方法是在批处理作业之外的某个时间将其全部编译、存储在单个转储文件中并让各个进程加载转储文件。

有没有人对这种情况有任何经验,或者你能给出很好的理由说明它会或不会起作用吗?如果可以合理地获得任何显着收益,无论是在内存使用还是性能方面?潜伏在阴影中的陷阱是什么?

【问题讨论】:

  • 我没有明白为什么在 CLI 中使用 APC 会浪费时间?在各个调用之间不保留操作码是什么意思?
  • APC 必须在重新启动时重建操作码缓存。当与网络服务器一起使用时,只要计算机处于活动状态,它就会保持活动状态,但在 CLI 模式下,每个进程都有自己的 APC,因此对于每个进程,它必须重建操作码缓存。由于 APC 通过不必为每个 PHP 脚本构建操作码来提高性能,因此它几乎抵消了您可能拥有的任何性能优势。我正在想办法解决这个问题。
  • 希望这不会显得迟钝,但你试过了吗?这是一个聪明的解决方法,希望我自己考虑过。我之前遇到过这样的问题,并且更喜欢使用带有定时循环的 Node.js(并且永远)。
  • 在这种情况下编译时间真的很重要吗?在这种情况下,与运行时相比,它似乎非常小。
  • @wolfgang 该方案主要影响内存使用。我使用 CLI 模式并行运行任务(作为穷人的多线程)。每个任务需要的内存越少,我可以并行运行的任务就越多。

标签: php cron command-line-interface apc


【解决方案1】:

免责声明: APC 在 CLI 中运行时非常棒,而且非常棒,但它同样令人沮丧。以健康的耐心使用,彻底,如果您正在旋转,请远离问题,请记住您正在使用缓存,这就是为什么它似乎什么都不做,实际上什么都不做。删除转储文件,从基础开始,如果不起作用,忘记它尝试新机器,新操作系统,如果它正在工作,请制作副本,逐个扩展功能 - 有很多东西不起作用,如果它正在工作提交或制作副本,请添加另一部分并再次测试,以进行完整性检查,重新检查之前工作的副本,无论是否陈词滥调;如果一开始你没有成功再试一次,你就不能一直做同样的事情来期待新的结果。

准备好了吗?这就是你一直在等待的:

为 cli 启用 apc

apc.enable-cli=1

在每个 CLI 请求上创建、填充和销毁 APC 缓存并不理想

   - previous answer by unknown poster since removed.

你说得对,这很糟糕,让我们解决它好吗?

如果您尝试在 CLI 下使用 APC 但未启用,您将收到警告。

类似:

PHP Warning:  apc_bin_loadfile(): APC is not enabled, 
              apc_bin_loadfile not available.
PHP Warning:  apc_bin_dumpfile(): APC is not enabled, 
              apc_bin_dumpfile not available.

警告:我建议你不要在 php.ini 中启用 cli,这不值得沮丧,你会忘记你做了它并且对其他脚本有很多其他的头痛,相信我不值得,改用启动器脚本。 (见下文)

cli中的apc_loadfile和apc_dumpfile

根据mightye php 的评论,我们需要禁用apc.stat,否则您会收到警告

类似:

PHP Warning:  apc_bin_dumpfile(): Excluding some files from apc_bin_dump[file].  
              Cached files must be included using full path with apc.stat=0. 

启动器脚本 - php-apc.sh

我们将使用此脚本来启动启用 apc 的脚本(例如 ./php-apc.sh apc-cli.php),而不是直接更改 php.ini 中的属性。

#/bin/sh
php -d apc.enable_cli=1 -d apc.stat=0 $1

准备好使用基本功能了吗?你当然是 =)

基本 APC 持续存在 - apc-cli.php

<?php
/** check if dump file exists, you don't want to use file_exists */
if (false !== $dump_file = stream_resolve_include_path('apc.dump'))
    /** so where were we lets have a look see shall we */
    if (false !== apc_bin_loadfile($dump_file))
        /** fetch what was stored last run just for fun */
        if (false !== $value = apc_fetch('my.awesome.apc.store'))
            echo "$value from apc\n";

/** store what gets fetched the next run just for fun */
apc_store('my.awesome.apc.store', 'awesome in cli');
/** what a shlep lets not do that all over again shall we */
apc_bin_dumpfile(array(),null,'apc.dump');

注意:为什么不使用 file_exists?因为file_exists == stat你看到了,我们想要获得apc.stat=0的奖励;所以;在包含路径中工作;使用绝对路径而不是相对路径 - 正如 stream_resolve_include_path(); 返回的那样,避免 include_oncerequire_once 使用非 *_once 对应的路径;在 不使用 APC(Muchos 重要传感器)时检查您的统计使用情况,借助 StreamWrapper 回显来调用方法 url_stat; 糟糕:致命的范围溢出错误!中止通知线程。见url_stat 消息:StreamWrapper 导致的错误超出了本次讨论的范围。

烟雾测试

使用启动器执行基本脚本

./php-apc.sh apc-cli.php

一大堆什么都没发生,这正是我们想要的,为什么还要使用缓存?如果它确实输出了任何东西,那么它就不起作用了,对不起。

应该有一个叫apc.dump的dump文件,看看能不能找到?如果你找不到它,那么它没有工作,对不起。

很好,我们有转储文件,没有错误,让我们再次运行它。

./php-apc.sh apc-cli.php

你想看的:

awesome in cli from apc

成功! =)

PHP 中很少有能像 APC 实现那样令人满意。
开心!

【讨论】:

  • 在 MAC OS X 10.6.8 上自定义编译 PHP 5.3.14 (cli)(构建时间:2012 年 7 月 7 日 21:32:43)
  • 优秀的答案!不过,对于统计数据的限制感到很遗憾。在我的特殊情况下,我需要包含一个相当大的框架,其中充斥着包含,这样我可能会为我完成我的工作。无论哪种方式,这都应该是开始试验的良好基础。
  • 您是否有任何经验,了解像这样在 CLI 中启用 APC 是否真的可以提高性能和/或内存使用率?
  • 没有任何限制,我试图说明的一点是,您希望从 spl 和 apc 的非统计优化中受益,而不是没有,但一切仍然会像往常一样工作。尝试使用 include_path 和 stream_resolve_include_path 来获取绝对路径,也许自定义自动加载器也会为您服务。如果您需要,我可能会挤出一些时间来帮助您。
  • 如果您的内存不足,您可能还有其他问题,并且无法替代保护,请确保您取消设置这些内存占用。分配空即。 $MyHugeCollection = null;unset($WhatIsTakingSoLong); 快得多,但是如果您不打算在下一次运行中重做长时间的操作,那么您对 ​​APC 会更满意。如果您仍然会做所有事情,那么走这条路几乎没有任何意义。
【解决方案2】:

绝对不会在 CLI 中使用它,因为当你重新启动它时,它几乎就像一开始就没有运行过一样!

使用 APC 的更好方法是让它始终在网络服务器本身上运行,这样当它处于活动状态时,它实际上会做它应该做的事情!

【讨论】:

  • 显然,我已经在网络服务器上运行了它。但我也想在 CLI 模式下使用它以减少内存配置文件。默认情况下,APC 不会有太大帮助,因为它每次运行都必须重新编译文件,但我想知道是否可以使用 APC 转储文件来跳过编译步骤。
  • 是的,只要在此期间没有变量发生变化,您就可以跳过编译步骤。所以基本上,如果有什么需要重新缓存,那么你需要重新编译!
【解决方案3】:

我尝试了 curl 和 APC。它可以工作

在 CLI 中使用这些命令

curl --data "param1=value2" http://testsite.com/test.php

所以它会将数据发布到 test.php,然后你在其中编写代码。

【讨论】:

  • 使用 HTTP 调用阻止性能关键脚本可能是您能做的最糟糕的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-16
相关资源
最近更新 更多