4

假设我将这些变量保存在 apc、memcached 和 eaccelerator 中:

  • article_1_0
  • article_1_1
  • article_3_2
  • article_3_3
  • article_2_4

如何删除所有以article_3_(最多可达 10000) 开头的缓存变量?

有没有办法列出缓存的变量?

4

5 回答 5

11

缓慢的解决方案

对于 APC:

$iterator = new APCIterator('user', '#^article_3_#', APC_ITER_KEY);
foreach($iterator as $entry_name) {
    apc_delete($entry_name);
}

对于加速器:

foreach(eaccelerator_list_keys() as $name => $infos) {
    if (preg_match('#^article_3_#', $name)) {
        eaccelerator_rm($name);
    }
}

对于 memcached,请查看@rik 的答案

正确的解决方案

一次过期多个键的一般解决方案是命名它们。为了使它们过期,您只需更改命名空间:

假设您有一组键“article_3_1”,“article_3_2”,...。您可以像这样存储它们:

$ns = apc_fetch('article_3_namespace');
apc_store($ns."_article_3_1", $value);
apc_store($ns."_article_3_2", $value);

像这样获取它们:

$ns = apc_fetch('article_3_namespace');
apc_fetch($ns."_article_3_1");

并通过增加命名空间使它们全部过期:

apc_inc('article_3_namespace');
于 2011-01-24T17:47:17.940 回答
2

尽管文档说 APCIterator 在 apc >= 3.1.1 中可用,但我在几个声称拥有 apc 3.1.9 的系统上,但是没有 APCIterator 存在。如果您没有 APCIterator 供您使用,请试一试:

$aCacheInfo = apc_cache_info('user');

foreach($aCacheInfo['cache_list'] as $_aCacheInfo)
    if(strpos($_aCacheInfo['info'], 'key_prefix:') === 0)
        apc_delete($_aCacheInfo['info']);

在此示例中,我们正在检查键中的前缀,但您可以使用 preg_match 等。al 并实现更接近 APCIterator 提供的东西。

于 2011-11-07T09:27:13.770 回答
1

如果有可能使用 memcached 的替代方案,scache支持结构化键空间。有了它,您可以将数据存储到嵌套路径:

scache_shset($conn, 'article/1/0', $data10);
scache_shset($conn, 'article/3/0', $data30);
scache_shset($conn, 'article/3/1', $data31);

并最终通过删除父节点来销毁数据

scache_shunset($conn, 'article/3');
于 2011-09-14T18:45:24.770 回答
1

一种方法可以从 memcache 中检索所有键,但它非常昂贵。

于 2011-01-24T17:47:06.570 回答
1

有一个 APCIterator 可以帮助您搜索 APC 中的键。实例化 APCIterator。

APCIterator::valid() 表示仍有键要迭代槽。APCIterator::key() 返回 apc 密钥。APCIterator::next() 将迭代器位置移动到下一项。

// APC
$iterator = new APCIterator('user', '/^article_3_/');

while($iterator->valid()) {
     apc_delete($iterator->key());
     // You can view the info for this APC cache value and so on by using 
     // $iterator->current() which is array
     $iterator->next();
}

对于 memcache,您可以使用Memcached并使用getAllKeys方法

// Memcached 
$m = new Memcached();
$m->addServer('mem1.domain.com', 11211);

$items = $m->getAllKeys();

foreach($items as $item) {
    if(preg_match('#^article_3_#', $item)) {
        $m->delete($item);
    }
}  
于 2014-12-02T11:34:51.777 回答