APC值随机消失

发布于 2024-10-08 05:51:14 字数 6311 浏览 9 评论 0原文

我使用 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)。

更新: 在下面的评论中,您会看到有人说 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
        (
        )

)

I'm using APC for storing a map of class names to class file paths. I build the map like this in my autoload function:

$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;
        }
    }   
}

I can see as more and more classes are loaded, they are added to the map, but at some point the apc_fetch returns NULL in the middle of a page request, instead of returning the map.

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}

Many times the cached value will also be gone between page requests.

What could be the reason for this?

I'm using APC as an extension (PECL) running PHP 5.3.

UPDATE:
In the comments below you will see people stating that APC is not persistent and that it is not to be trusted. But in my case the code is executed in one page request between 15-50ms. Shouldn't I be able to trust the APC for that long?

UPDATE:
It seems that the cache contains multiple entries with the same key, when it should only contain one - that is overwritten the value when invoking apc_store(). I hope this can help someone understand the problem. (I've disabled slam defense and write lock)

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
        (
        )

)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一个人的旅程 2024-10-15 05:51:14

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

It's not persistent storage.
You may improve it by increasing memory size of APC but anyway, there are no warranties.
So you should reinit values if you see they are dropped.

妄司 2024-10-15 05:51:14

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

首先,正如许多人正确指出的那样。

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 调用将其存储在缓存中。这使得点击率上升,而每个键的缓存条目下降——而且我的代码现在运行得很快。

I will try to answer my own question from what I've learned.

Firstly like many people has rightly pointed out.

APC is not persistent.

It was for me hard to accept this statement without a practical explanation or even better a guide on how to work with it.

I've come to find that there are some rules or rather pitfalls to be aware of - many still eludes me. Using the APC API means using apc_fetch and apc_store both of these can fail, or as it is more correctly put, miss. And why you sometimes receive NULL when you expected data is where the mystery lies.

Here are some random bits of information:

  • If you try to store a value before the TTL runs out a new entry will be created. So slow down writing or decrease TTL.

The number of seconds a cache entry is
allowed to idle in a slot in case this
cache entry slot is needed by another
entry. Leaving this at zero means that
APC's cache could potentially fill up
with stale entries while newer entries
won't be cached. -
http://php.net/manual/en/apc.configuration.php

  • Play around with apc.ttl and apc.user_ttl till you find something that suits you - until you see lots of hits and not to many entries.

  • apc_fetch and apc_store can return NULL for a number of reasons, some hinted above, such as ttl another reason can be a key fetch timeout. But the point is design-around it. Expect this.

If you like me have been feeling very frustated about APC's behaviour have a look at this article pointed out to me by scoates: http://phpadvent.org/2010/share-and-enjoy-by-gopal-vijayaraghavan . It will not give you much answers but some basic knowledge about cache design and perhaps like me some relief in the fact I'm not alone :)

In my case with the class-path issue described in my question, I decided to use a local variable to build up the cache and then at the end storing it in the cache with one single apc_store invocation. This brought the hits way up and the cache entries per key way down - and my code is now running fast.

孤独陪着我 2024-10-15 05:51:14

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

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

APC IS persistent but separate for each apache process.

PHP mentains a separate APC CACHE storage for each apache process, which is perfectly normal because each apache process has his own memory space.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文