delete cache by prefix in apc / memcache / eaccelerator

烈酒焚心 提交于 2019-12-04 09:04:23
Arnaud Le Blanc

The slow solution

For APC:

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

For eaccelerator:

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

For memcached, look at @rik's answer

The proper solution

The general solution for expiring multiple keys at once is to namespace them. For expiring them, you just have to change the namespace:

Say you have a group of keys "article_3_1", "article_3_2", .... You can store them like this:

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

Fetch them like this:

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

And expire them all by just incrementing the namespace:

apc_inc('article_3_namespace');

Although the docs say APCIterator is available in apc >= 3.1.1, I'm on several systems that claim to have apc 3.1.9, however there is no APCIterator present. If you don't have APCIterator at your disposal, give something like this a whirl:

$aCacheInfo = apc_cache_info('user');

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

In this example we're checking for a prefix in the key, but you could use preg_match et. al and achieve something closer to what APCIterator provides.

There is a way to retrieve all keys from memcache but it's very expensive.

If there is possibility to use alternatives for memcached, scache supports structured keyspaces. With it you could store data to nested paths :

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

and eventually destroy data by deleting the parent node

scache_shunset($conn, 'article/3');

There is an APCIterator which helps you search through the keys in APC. Instantiate the APCIterator.

APCIterator::valid() means that there are keys still to iterate trough. APCIterator::key() returns you the apc key. APCIterator::next() moves the iterator position to the next item.

// 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();
}

For memcache you can use Memcached and use getAllKeys method

// 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);
    }
}  
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!