【问题标题】:apciterator can't retrieve items after certain amount of timeapciterator 在一定时间后无法检索项目
【发布时间】:2016-10-24 10:57:09
【问题描述】:

**更新 06/23 **

此时,我能够将问题隔离为一个简单的示例。首先我存储一些示例项目:

apc_add('MY_APC_TESTA_1','1');
apc_add('MY_APC_TESTA_2','2');
apc_add('MY_APC_TESTA_3','3');
apc_add('MY_APC_TESTB_4','4');
apc_add('MY_APC_TESTB_5','5');
apc_add('MY_APC_TESTB_6','6');

然后我使用 APCIterator 检索项目,使用 foreach 循环对它们进行计数,另外使用 apciterator 类的 getTotalCounts 方法进行双重检查。

$iterator = new APCIterator('user', '/^MY_APC/', APC_ITER_VALUE);

function showCache() {

    echo "keys in cache<br>-------------<br>";
    foreach ($items AS $key => $value) {
        echo $key . "<br>";
    }
}


$i = 0;    
foreach ($iterator as $current_item) {
        $i++;
}

echo 'getTotalCount: '.$iterator->getTotalCount().'<br>'; // output: 6
echo 'foreach count: '.$i.'<br>'; // output:  6

showCache();

在存储我得到这个输出的项目后立即调用这个脚本:

getTotalCount: 6
foreach count: 6
keys in cache
-------------
MY_APC_TESTA_1
MY_APC_TESTA_2
...

几个小时或一天后调用这个脚本我会收到这个输出:

getTotalCount: 6
foreach count: 0
keys in cache
-------------

因此,您可以看到迭代器类仍然可以使用其方法 getTotalCount 检索总计数,但 foreach 循环会带来空结果,尽管它在几个小时前工作。这就是为什么我的缓存处理程序无法工作的原因,因为它们将 apciterator 与 apc_delete($iterator) 结合使用来获取相应的项目并在进行修改后清除它们。由于 foreach/array 是空的,因此没有什么可删除的。这是一个巨大的问题。我不认为这是预期的行为。任何想法这怎么可能?

我的 VPS 上有以下设置:

  • CentOS 7
  • Nginx 与 PHP-FPM
  • PHP 5.4.16
  • APC 3.1.13

APC 设置:

apc.cache_by_default    1
apc.canonicalize    1
apc.coredump_unmap  0
apc.enable_cli  0
apc.enabled 1
apc.file_md5    0
apc.file_update_protection  2
apc.filters 
apc.gc_ttl  3600
apc.include_once_override   0
apc.lazy_classes    0
apc.lazy_functions  0
apc.max_file_size   1M
apc.mmap_file_mask  /tmp/apc.Z1n8dS
apc.num_files_hint  512
apc.preload_path    
apc.report_autofilter   0
apc.rfc1867 0
apc.rfc1867_freq    0
apc.rfc1867_name    APC_UPLOAD_PROGRESS
apc.rfc1867_prefix  upload_
apc.rfc1867_ttl 3600
apc.serializer  default
apc.shm_segments    1
apc.shm_size    256M
apc.shm_strings_buffer  4M
apc.slam_defense    1
apc.stat    1
apc.stat_ctime  0
apc.ttl 7200
apc.use_request_time    1
apc.user_entries_hint   4096
apc.user_ttl    7200
apc.write_lock  1

【问题讨论】:

  • 您的正则表达式似乎与其余键不匹配,如果将其更改为:new APCIterator('user', '/^resource\/schx_web\/.*/', APC_ITER_KEY); 会发生什么?
  • @Paradoxis 这将返回bool(false) 并且没有任何内容被删除。然而进一步调试:APCIterator::getTotalCount 返回的数字与使用 foreach 循环遍历 $iterator 变量时被删除的项目不匹配。所以问题一定出在这里……
  • 尝试重启你的网络服务器
  • APC 面板将列出过期的条目,当您尝试阅读它们时,它们真的会被删除。也许迭代器会自动跳过这些?您是否也尝试过转储价值?
  • @Paradoxis 那也没有帮助。我想这确实与计数的差异有关。

标签: php caching iterator apc


【解决方案1】:

APCIterator 错误地只返回比 apc.ttl 更年轻的缓存条目,但它在 getTotalCount() 返回的数字中包含这些条目。

我已在此处提交了针对此错误的拉取请求:https://github.com/krakjoe/apcu/pull/253

【讨论】:

    猜你喜欢
    • 2015-01-22
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 2016-11-10
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多