比如,我有一些具有相同前缀的缓存项,例如
'app_111111', 'app_222222', 'app_333333', ...
我能通过哪些memcached命令删除这些名为 'app_xxxxxx' 的项吗?
->是否可以通过任何Memcached命令删除这些名为'app_xxxxxx'的项?
Memcached默认不提供此功能,因此您需要自己构建。
我的解决方法是在我的应用程序中定义前缀(或命名空间)以表示键组。我在Memcached中设置的任何键都有该前缀。每当我想要从Memcached“删除”内容时,我只需更改前缀。每当我想要在Memcached中查找键时,我将该前缀添加到它上面。
在您的情况下,您可以首先将前缀设置为MyAppPrefix1
,这样您的键将被存储为MyAppPrefix1::app_333333
,MyAppPrefix1::app_444444
等。
稍后,当您想要“删除”这些条目时,请将您的应用程序设置为使用MyAppPrefix2
。然后,当您尝试从Memcached获取名为app_333333
的键时,它将查找MyAppPrefix2::app_333333
,第一次找不到,就像已被删除一样。
这个php函数怎么样:
function deletekeysbyindex($prefix) {
$m = new Memcached();
$m->addServer('localhost', 11211);
$keys = $m->getAllKeys();
foreach ($keys as $index => $key) {
if (strpos($key,$prefix) !== 0) {
unset($keys[$index]);
} else {
$m->delete($key);
}
}
return $keys;
}
删除以$prefix开始的键,并返回所有已删除键的列表。我刚刚在一个共享服务器上运行了30,000多个键,速度非常快-可能不到一秒钟。
getAllKeys()
方法在何时和为何可能不能正常工作的信息...你能提供一些启示吗?文档并没有太大帮助。 - But those new buttons though.. $prefix = 'MyApp::Test';
$len = strlen($prefix);
$proc = popen('/usr/local/bin/memdump --servers=localhost', 'r');
while (($key = fgets($proc)) !== false) {
if (substr_compare($key, $prefix, 0, $len) === 0) {
$memcached->delete(substr($key, 0, -1));
}
}
我们不能在一个请求中完成对memcache的操作,我们只能这样做:
public function clearByPrefix($prefixes = array()) {
$prefixes = array_unique($prefixes);
$slabs = $this->memcache->getExtendedStats('slabs');
foreach ($slabs as $serverSlabs) {
if ($serverSlabs) {
foreach ($serverSlabs as $slabId => $slabMeta) {
if (is_int($slabId)) {
try {
$cacheDump = $this->memcache->getExtendedStats('cachedump', (int) $slabId, 1000);
} catch (Exception $e) {
continue;
}
if (is_array($cacheDump)) {
foreach ($cacheDump as $dump) {
if (is_array($dump)) {
foreach ($dump as $key => $value) {
$clearFlag = false;
// Check key has prefix or not
foreach ($prefixes as $prefix) {
$clearFlag = $clearFlag || preg_match('/^' . preg_quote($prefix, '/') . '/', $key);
}
// Clear cache
if ($clearFlag) {
$this->clear($key);
}
}
}
}
}
}
}
}
}
}
然后像这样调用该函数:
$prefixes = array();
array_push($prefixes, 'prefix1_');
array_push($prefixes, 'prefix2_');
array_push($prefixes, 'prefix3_');
$this->clearByPrefix($prefixes);