问题
Let's assume I have these variables saved in apc, memcached and eaccelerator:
article_1_0
article_1_1
article_3_2
article_3_3
article_2_4
How can I delete all cached variables that starts with article_3_
(they can reach up to 10000) ?
is there any way to list the cached variables ?
回答1:
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');
回答2:
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.
回答3:
There is a way to retrieve all keys from memcache but it's very expensive.
回答4:
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');
回答5:
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);
}
}
来源:https://stackoverflow.com/questions/4785153/delete-cache-by-prefix-in-apc-memcache-eaccelerator