【问题标题】:APC, disk hits, and requires/includesAPC、磁盘命中和需要/包含
【发布时间】:2012-07-02 21:02:18
【问题描述】:

很简单的问题,但我无法确定。 PHP 如何处理已经被 APC 缓存的文件的 requires/includes 行为?我的理解是,这个缓存主要保存 PHP 编译已经缓存的文件,但我不清楚它是否也保存了查找/获取文件所需的磁盘命中;所以,是吗?还是 PHP 会撞到磁盘,即使操作码已经被缓存了,唯一的区别是它不再进行编译过程?

我想认为 requires/includes 神奇地知道文件已缓存,因此借助 APC 直接从内存中获取它,但我刚刚意识到我没有理由假设这是这种情况,因此我问。

【问题讨论】:

    标签: php apc


    【解决方案1】:

    我认为 APC 手册中解释了您关于此主题的问题,但它有点隐藏。您必须阅读configuration 部分才能找到它。尤其是查看apc.stat 配置选项,其中说明了这一点:

    ... 这默认为开启,强制 APC 统计(检查)脚本开启 每个请求,以确定它是否已被修改。如果已经 修改它将重新编译并缓存新版本。如果这个设置 已关闭,APC 将不会检查
    ...
    对于包含/必需的文件,此选项也适用,但请注意 对于相对路径包括(任何不以 / 开头的路径 Unix) APC 必须检查才能唯一标识文件。如果你 使用绝对路径包括 APC 可以跳过统计信息并使用该绝对路径 路径作为文件的唯一标识符。

    所以看起来 APC 缓存所需/包含的文件的方式与原始脚本大致相同,如果您通过文件的绝对路径包含/需要。如果您使用的是相对路径(很多人都这样做),则需要磁盘命中才能找到完整的文件名。

    【讨论】:

    • 从我能读到的这个设置告诉 APC 是否在文件中查找更改以重建操作码缓存,但操作码缓存是一回事,初始文件查找由 include /require 是另一个;这不一定是相关的,也没有说明是否相关。也就是说,如果 apc.stat 设置为 off,APC 可能不会检查磁盘上的更改,但是 requires/includes 会跳过文件查找过程并从内存中获取它吗?我还不清楚。
    • @Mahn:只要它们被缓存,它就会从内存中获取它们
    【解决方案2】:

    实际上,APC 确实为 *once 变体(include_once、require_once)打开系统调用。 您可以使用 strace 轻松检查这一点。

    那是因为 *once 的代码略有不同,调用 zend_stream_open 在调用 compile_filename(被 apc 覆盖)之前:

    https://github.com/php/php-src/blob/master/Zend/zend_execute.h

    错误跟踪器中也有一个未解决的问题: https://bugs.php.net/bug.php?id=59372

    【讨论】:

      【解决方案3】:

      APC 覆盖 Zend 引擎中的 zend_compile_file 函数,它负责定位和打开实际文件;多亏了这一点,如果文件已经被缓存,它能够在磁盘命中发生之前“劫持”它们。

      因此,是的,如果缓存了文件,则从内存中提供文件。

      来源:APC Technotes 和 Zend 引擎源代码,特别是 zend_language_scanner.c

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-06
        • 2015-07-14
        • 2011-10-16
        • 2021-11-28
        • 2020-03-17
        • 2018-08-14
        相关资源
        最近更新 更多