例如,我有些缓存的项目有相同的前缀,如如何删除memcached中具有相同前缀键的项目?
'app_111111', 'app_222222', 'app_333333', ...
我可以用任何memcached的命令删除这些“app_xxxxxx”项目?
例如,我有些缓存的项目有相同的前缀,如如何删除memcached中具有相同前缀键的项目?
'app_111111', 'app_222222', 'app_333333', ...
我可以用任何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;
}
删除以$前缀开头键和返回删除了所有键的列表。我刚刚在共享服务器上运行了30,000多个密钥,并且速度非常快 - 大概不到一秒钟。
这不能保证能正常工作。 http://php.net/manual/en/memcached.getallkeys.php “由于memcache不能保证返回所有密钥,所以您也不能认为所有密钥都已返回。” –
感谢您指出这一点@TimMartens。我想这跟你能得到的一样好?我希望有更多关于getAllKeys()方法何时以及为什么会出现的更多信息。你能对此有所了解吗?文档是相当无益的。 – billynoah
我们不能只在一个请求中执行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);
即使你的代码看起来很容易理解,你也可以解释它的作用,以及为什么你认为这个解决方案可以帮助提问者。顺便说一句,preg_match当你可以调用strpos时,确实是一个矫枉过正的问题。 –
也许我应该在我的代码中添加更多评论:) 关于preg_match,我不认为这太过矫枉过正。你知道,对于这种情况只是一件简单的事情。我甚至打算将来的正则表达式会更复杂。 :)感谢您的评论兄弟! –
这是一个工作,虽然有点慢黑客攻击。在拥有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));
}
}
http://stackoverflow.com/questions/1595904/memcache-and-wildcards –