【发布时间】:2010-12-08 10:18:38
【问题描述】:
我只是想知道是否有一种方法可以使用通配符作为键值来清除内存缓存。
假设我有一个带有键“1234~foo”和另一个“1234~foo~bar”的缓存。
我有什么办法可以通过使用 clear("1234*") 之类的方法来清除缓存并从上面清除它们吗?
我希望这是有道理的。
谢谢。
【问题讨论】:
标签: memcached
我只是想知道是否有一种方法可以使用通配符作为键值来清除内存缓存。
假设我有一个带有键“1234~foo”和另一个“1234~foo~bar”的缓存。
我有什么办法可以通过使用 clear("1234*") 之类的方法来清除缓存并从上面清除它们吗?
我希望这是有道理的。
谢谢。
【问题讨论】:
标签: memcached
不,没有直接简单的方法可以做到这一点。 FAQ 解决了这个问题,并提供了一种解决方法:
按命名空间删除
虽然 memcached 不支持任何类型的通配符删除或按命名空间删除(因为没有命名空间),但可以使用一些技巧来模拟这一点。但是,它们确实需要额外访问 memcached 服务器。
在 PHP 中使用名为 foo 的命名空间的示例:
$ns_key = $memcache->get("foo_namespace_key");
// if not set, initialize it
if($ns_key===false) {
$ns_key=rand(1, 10000);
$memcache->set("foo_namespace_key", $ns_key);
}
// cleverly use the ns_key
$my_key = "foo_".$ns_key."_12345";
$my_val = $memcache->get($my_key);
//To clear the namespace do:
$memcache->increment("foo_namespace_key");
【讨论】:
Eric Petroelje 关于命名空间解决方案的说明:
请记住,您不知道 memcached 何时会驱逐您的命名空间键。 Memcache 可能会驱逐您的命名空间键,然后在尝试设置新键时,它有 1 到 10000 的概率会选择相同的索引键 - 这意味着您将获得“脏”结果。这不太可能,但归根结底,它并不安全。
Poul Vernon 的解决方案也存在同样的问题。
一个安全的解决方案是为“指针键”/“命名空间键”使用可靠的存储(例如磁盘)。
【讨论】:
这个函数在php中怎么样:
function deleteKeysByIndex($search) {
$m = new Memcached();
$m->addServer('localhost', 11211);
$keys = $m->getAllKeys();
foreach ($keys as $index => $key) {
if (strpos($key,$search) !== false) {
$m->delete($key);
} else {
unset($keys[$index]);
}
}
// returns an array of keys which were deleted
return $keys;
}
删除以 $prefix 开头的键并返回所有已删除键的列表。我刚才在共享服务器上运行了 30,000 多个密钥,而且速度非常快 - 可能不到一秒。
【讨论】:
$m->deleteMulti($keys)来实现。php.net/manual/en/memcached.deletemulti.php
delete 和deleteMulti 在性能方面是否有任何区别,但我认为您只能真正观察到 1M+ 键的任何区别。
$search 开头。这将删除任何位置包含$search 的键。
为“1234”创建一个内存缓存条目,并在其中存储相关键的数组。在您的删除例程中读取并遍历这些键以删除。
【讨论】: