在apc / memcache / eaccelerator中按前缀删除缓存

时间:2011-01-24 17:41:01

标签: php memcached apc eaccelerator

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

  • article_1_0
  • article_1_1
  • article_3_2
  • article_3_3
  • article_2_4

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

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

5 个答案:

答案 0 :(得分:11)

缓慢的解决方案

对于APC:

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

对于eaccelerator:

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

对于memcached,请查看@rik's answer

正确的解决方案

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

假设您有一组键“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');

答案 1 :(得分: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等。并实现更接近APCIterator提供的东西。

答案 2 :(得分:1)

a way to retrieve all keys from memcache,但它非常昂贵。

答案 3 :(得分: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');

答案 4 :(得分: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);
    }
}