[英]How to delete items with same prefix key in memcached?
For example, I have some cached items with same prefix, such as 例如,我有一些具有相同前缀的缓存项,例如
'app_111111', 'app_222222', 'app_333333', ...
Can I remove such 'app_xxxxxx' items by any memcached commands? 我可以通过任何memcached命令删除这样的'app_xxxxxx'项吗?
Memcached does not offer this functionality out of the box so you have to build it in yourself. Memcached不提供开箱即用的功能,因此您必须自己构建它。
The way I solve this is by defining a prefix (or namespace) in my application for groups of keys. 我解决这个问题的方法是在我的应用程序中为键组定义一个前缀(或命名空间)。 Any key that I set in memcached has that prefix before it. 我在memcached中设置的任何键都有前缀。 Whenever I want to "delete" stuff from Memcached, I just change the prefix. 每当我想从Memcached“删除”东西时,我只需更改前缀。 And whenever I want to lookup a key in Memcached, I add that prefix to it. 每当我想在Memcached中查找密钥时,我都会添加该前缀。
In your case, you could start by setting the prefix to, say, MyAppPrefix1
, so your keys will be stored as MyAppPrefix1::app_333333
, MyAppPrefix1::app_444444
. 在您的情况下,您可以首先将前缀设置为MyAppPrefix1
,因此您的密钥将存储为MyAppPrefix1::app_333333
, MyAppPrefix1::app_444444
。
Later on when you want to "delete" these entries, set your application to use MyAppPrefix2
. 稍后当您要“删除”这些条目时,请将您的应用程序设置为使用MyAppPrefix2
。 Then, when you try to get a key from Memcached called app_333333
, it will look for MyAppPrefix2::app_333333
and will not find it the first time around, as if it had been deleted. 然后,当您尝试从Memcached获取一个名为app_333333
的密钥时,它将查找MyAppPrefix2::app_333333
并且第一次找不到它,就像它已被删除一样。
How about this function in php: 在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;
}
Deletes keys beginning with $prefix and returns a list of all keys removed. 删除以$ prefix开头的键,并返回已删除的所有键的列表。 I ran this on 30,000+ keys just now on a shared server and it was pretty quick - probably less than one second. 我刚刚在共享服务器上运行了30,000多个密钥,而且速度非常快 - 可能不到一秒钟。
We can not do that in only one request to memcache. 我们不能只在memcache的一个请求中这样做。 We just can do this: 我们可以做到这一点:
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);
}
}
}
}
}
}
}
}
}
}
And call this function like this: 并调用此函数:
$prefixes = array();
array_push($prefixes, 'prefix1_');
array_push($prefixes, 'prefix2_');
array_push($prefixes, 'prefix3_');
$this->clearByPrefix($prefixes);
This is a hack that works, albeit a bit slow. 这是一个有效的黑客,虽然有点慢。 On a server with 0.6 million keys, it took half a second to complete. 在拥有60万个密钥的服务器上,完成需要半秒钟。
$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));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.