【问题标题】:APC values randomly disappearAPC 值随机消失
【发布时间】:2010-12-17 08:32:41
【问题描述】:

我正在使用 APC 将类名映射存储到类文件路径。我在自动加载功能中像这样构建地图:

$class_paths = apc_fetch('class_paths');

// If the class path is stored in application cache - search finished.

if (isset($class_paths[$class])) {
    return require_once $class_paths[$class];

// Otherwise search in known places

} else {

    // List of places to look for class

    $paths = array(
        '/src/',
        '/modules/',
        '/libs/',
    );

    // Search directories and store path in cache if found.

    foreach ($paths as $path) {
        $file = DOC_ROOT . $path . $class . '.php';
        if (file_exists($file)) {
            echo 'File was found in => ' . $file . '<br />';

            $class_paths[$class] = $file;
            apc_store('class_paths', $class_paths);
            return require_once $file;
        }
    }   
}

我可以看到随着越来越多的类被加载,它们被添加到地图中,但在某些时候apc_fetch 在页面请求中间返回NULL,而不是返回地图。

Getting => class_paths
Array
(
    [MCS\CMS\Helper\LayoutHelper] => /Users/mbl/Documents/Projects/mcs_ibob/core/trunk/src/MCS/CMS/Helper/LayoutHelper.php
    [MCS\CMS\Model\Spot] => /Users/mbl/Documents/Projects/mcs_ibob/core/trunk/src/MCS/CMS/Model/Spot.php
)
Getting => class_paths
{null}

很多时候缓存的值也会在页面请求之间消失。

这可能是什么原因?

我将 APC 用作运行 PHP 5.3 的扩展 (PECL)。

更新: 在下面的 cmets 中,您会看到有人说 APC 不是持久性的并且不值得信任。但在我的情况下,代码在 15-50 毫秒之间在一页请求中执行。难道我不能信任 APC 这么久吗?

更新: 似乎缓存包含具有相同键的多个条目,而它应该只包含一个 - 在调用 apc_store() 时会覆盖该值。我希望这可以帮助某人理解这个问题。 (我已经禁用了满贯防御和写锁)

Array
(
    [num_slots] => 4099
    [ttl] => 0
    [num_hits] => 0
    [num_misses] => 3
    [num_inserts] => 9678
    [expunges] => 0
    [start_time] => 1293109072
    [mem_size] => 40064
    [num_entries] => 8
    [file_upload_progress] => 1
    [memory_type] => mmap
    [locking_type] => file
    [cache_list] => Array
        (
            [0] => Array
                (
                    [info] => fSchema::mysql::fORM::default::/Users/mbl/Documents/Projects/mcs_ibob/core/trunk/public_html/::::column_info
                    [ttl] => 0
                    [type] => user
                    [num_hits] => 0
                    [mtime] => 1293109072
                    [creation_time] => 1293109072
                    [deletion_time] => 0
                    [access_time] => 1293109072
                    [ref_count] => 0
                    [mem_size] => 12456
                )

            [1] => Array
                (
                    [info] => mcs:odk:class_paths
                    [ttl] => 3600
                    [type] => user
                    [num_hits] => 0
                    [mtime] => 1293109072
                    [creation_time] => 1293109072
                    [deletion_time] => 0
                    [access_time] => 1293109072
                    [ref_count] => 0
                    [mem_size] => 648
                )

            [2] => Array
                (
                    [info] => mcs:odk:class_paths
                    [ttl] => 3600
                    [type] => user
                    [num_hits] => 0
                    [mtime] => 1293109072
                    [creation_time] => 1293109072
                    [deletion_time] => 0
                    [access_time] => 1293109072
                    [ref_count] => 0
                    [mem_size] => 648
                )

            [3] => Array
                (
                    [info] => mcs:odk:class_paths
                    [ttl] => 3600
                    [type] => user
                    [num_hits] => 0
                    [mtime] => 1293109072
                    [creation_time] => 1293109072
                    [deletion_time] => 0
                    [access_time] => 1293109072
                    [ref_count] => 0
                    [mem_size] => 648
                )

            [4] => Array
                (
                    [info] => mcs:odk:class_paths
                    [ttl] => 3600
                    [type] => user
                    [num_hits] => 0
                    [mtime] => 1293109072
                    [creation_time] => 1293109072
                    [deletion_time] => 0
                    [access_time] => 1293109072
                    [ref_count] => 0
                    [mem_size] => 648
                )

            [5] => Array
                (
                    [info] => mcs:odk:class_paths
                    [ttl] => 3600
                    [type] => user
                    [num_hits] => 0
                    [mtime] => 1293109072
                    [creation_time] => 1293109072
                    [deletion_time] => 0
                    [access_time] => 1293109072
                    [ref_count] => 0
                    [mem_size] => 648
                )

            [6] => Array
                (
                    [info] => mcs:odk:class_paths
                    [ttl] => 3600
                    [type] => user
                    [num_hits] => 0
                    [mtime] => 1293109072
                    [creation_time] => 1293109072
                    [deletion_time] => 0
                    [access_time] => 1293109072
                    [ref_count] => 0
                    [mem_size] => 648
                )

            [7] => Array
                (
                    [info] => fSchema::mysql::fORM::default::/Users/mbl/Documents/Projects/mcs_ibob/core/trunk/public_html/::::merged_column_info
                    [ttl] => 0
                    [type] => user
                    [num_hits] => 0
                    [mtime] => 1293109072
                    [creation_time] => 1293109072
                    [deletion_time] => 0
                    [access_time] => 1293109072
                    [ref_count] => 0
                    [mem_size] => 23720
                )

        )

    [deleted_list] => Array
        (
        )

)

【问题讨论】:

  • @Michael:可能是因为你的缓存已满所以它会丢弃它
  • @RageZ:我只存储了几个字符串。经常/快速点击apc_store 可能是个问题吗?
  • @Michael:我从未使用过 APC,但如果它与 memcache 相同,则无法保证系统将永远保留您的数据。所以我同意 BarsMonster 的回答。
  • @RageZ 但我们仍然在谈论每次命中类自动加载函数之间的毫秒数,APC 必须存储比这更长的值?
  • Gopal(APC 的主要作者之一)最近发表的这篇文章可能会为您的问题提供一些不太技术性的信息(故意发表评论,而不是回答):phpadvent.org/2010/share-and-enjoy-by-gopal-vijayaraghavan

标签: php apc


【解决方案1】:

它不是持久存储。 您可以通过增加 APC 的内存大小来改进它,但无论如何,没有保证。 因此,如果您看到它们被删除,您应该重新初始化值。

【讨论】:

  • 不持久到什么程度?完全没有规则? :)
  • 是的,它可能随时清除您的记录。
  • 嗯,有人能告诉我 APC 规范说“必须随机删除元素并无缘无故地刷新自己”xD
  • Hannes,没有人说它是随机的。但 APC 不是持久的。
【解决方案2】:

我将尝试根据我所学到的知识来回答我自己的问题。

首先就像许多人正确指出的那样。

APC is not persistent.

如果没有实际的解释,甚至没有更好的使用指南,我很难接受这种说法。

我发现有一些规则或者更确切地说是需要注意的陷阱 - 很多我仍然无法理解。使用 APC API 意味着使用 apc_fetchapc_store 这两个都可能失败,或者更准确地说,错过。以及为什么您有时会收到NULL,而您期望的数据就是其中的奥秘所在。

以下是一些随机的信息:

  • 如果您尝试在 TTL 用完之前存储一个值,则会创建一个新条目。所以放慢写入速度或减少 TTL。

缓存条目的秒数 允许在插槽中空闲,以防万一 另一个需要缓存条目槽 入口。将其保留为零意味着 APC 的缓存可能会填满 有过时的条目,而较新的条目 不会被缓存。 - http://php.net/manual/en/apc.configuration.php

  • 玩转apc.ttlapc.user_ttl,直到找到适合你的东西 - 直到你看到很多热门而不是很多条目。

  • apc_fetchapc_store 可以返回 NULL 的原因有很多,上面有一些提示,例如 ttl 另一个原因可能是密钥获取超时。但关键是围绕它进行设计。期待这个。

如果您像我一样对 APC 的行为感到非常沮丧,请查看 scoates 向我指出的这篇文章:http://phpadvent.org/2010/share-and-enjoy-by-gopal-vijayaraghavan。它不会给你太多答案,而是一些关于缓存设计的基本知识,也许像我一样因为我并不孤单而感到宽慰:)

在我的问题中描述的类路径问题的情况下,我决定使用一个局部变量来构建缓存,然后最后通过一个 apc_store 调用将其存储在缓存中。这使点击率上升,每个键的缓存条目下降 - 我的代码现在运行得很快。

【讨论】:

    【解决方案3】:

    APC 是持久的,但对于每个 apache 进程都是独立的。

    PHP 为每个 apache 进程维护一个单独的 APC CACHE 存储,这是完全正常的,因为每个 apache 进程都有自己的内存空间。

    【讨论】:

    • 那么同一个用户不会在两个请求之间“命中”同一个进程?
    • 我认为你错了。 APC 是本地服务器的全局缓存(没有网络通信,没有来自其他服务器的访问)。
    • 当您使用 CGI 时不会。每个 PHP CGI 进程都有自己的 apc 缓存实例。
    猜你喜欢
    • 1970-01-01
    • 2012-12-03
    • 2016-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 2020-02-03
    相关资源
    最近更新 更多