APC值随机消失 [英] APC values randomly disappear
问题描述
我正在使用APC来存储类名到类文件路径的映射.我在自动加载功能中构建了这样的地图:
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;
}
}
}
我可以看到,随着越来越多的类被加载,它们被添加到地图中,但是在某些情况下,apc_fetch
在页面请求的中间返回NULL
,而不是返回地图.
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.
这可能是什么原因?
我正在使用APC作为运行PHP 5.3的扩展(PECL).
I'm using APC as an extension (PECL) running PHP 5.3.
更新: 在下面的评论中,您会看到人们指出APC不是持久性的,并且不值得信赖.但就我而言,代码是在15-50毫秒之间的一页请求中执行的.我应该不能这么长时间信任APC吗?
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?
更新:
似乎高速缓存包含具有相同键的多个条目,而它只应包含一个键-调用apc_store()
时将覆盖该值.我希望这可以帮助某人理解问题. (我已经禁用了大满贯防御功能并写了锁)
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
(
)
)
推荐答案
我将尝试根据所学知识回答自己的问题.
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.
我发现有些规则或陷阱值得我们注意-许多仍然使我难以理解.使用APC API意味着同时使用apc_fetch
和apc_store
都可能失败,或者更准确地说,是未命中.以及为什么当您期望数据是神秘之处时有时会收到NULL
的原因.
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:
- 如果您尝试在TTL用尽之前存储值,则会创建一个新条目.因此,请减慢写入速度或降低TTL.
高速缓存条目的秒数 允许在插槽中闲置以防这种情况 另一个需要缓存入口插槽 入口.将此保持为零意味着 APC的缓存可能会填满 使用陈旧条目,而使用较新条目 将不会被缓存. -- http://php.net/manual/en/apc.configuration.php
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
-
试玩
apc.ttl
和apc.user_ttl
,直到找到适合自己的内容-直到看到很多匹配,而不是很多条目为止.Play around with
apc.ttl
andapc.user_ttl
till you find something that suits you - until you see lots of hits and not to many entries.apc_fetch
和apc_store
可以返回NULL
,例如上面提到的一些原因,例如ttl另一个原因可能是密钥获取超时.但是重点是围绕它的设计.期待这个.apc_fetch
andapc_store
can returnNULL
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.如果您像我一样对APC的行为感到非常沮丧,请查看由scoates向我指出的这篇文章:
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 :)
对于我在问题中描述的类路径问题,我决定使用局部变量来构建缓存,然后最后通过一次
apc_store
调用将其存储在缓存中.这使命中率上升,每个键的缓存条目下降,而我的代码现在运行得很快.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.这篇关于APC值随机消失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!