Issue
Very similar questions have been posted and answered. However every solution I found so far is using php Memcached extension rather than Memcache. I am trying to delete/expire all memcache items that begin with a predefined key. For example, so_something
, so_something_else ...
. Any help is much appreciated.
Solution
After some research I figured how to do it using standard Memcache commands. But, unfortunately this will man trips to the memcache server so it is to be used with care; in my case it is used only after deployment:
/**
* Helper function to expire memcache entries with a specific key prefix.
*
* @param string $key_prefix
* The memcache key prefix.
* @param array $servers
* Array of used memcache servers.
* @return array
*
*/
function memcache_delete_by_key($key_prefix = '', $servers = array()) {
$mc = new Memcache();
$delete_keys = array();
foreach ($servers as $server => $default) {
list($host, $port) = explode(':', $server);
$mc->addServer($host, $port);
// Extract all the keys from Memcache.
$stats = memcache_command($server, $port, "stats items");
$stat_lines = explode("\r\n", $stats);
$slabs = array();
$keys = array();
foreach ($stat_lines as $line) {
if (preg_match("/STAT items:([\d]+):number ([\d]+)/", $line, $matches)) {
if (isset($matches[1]) && !in_array($matches[1], $slabs)) {
$slabs[] = $matches[1];
$string = memcache_command($server, $port, "stats cachedump " . $matches[1] . " " . $matches[2]);
preg_match_all("/ITEM (.*?) /", $string, $matches);
$keys[] = $matches[1];
}
}
}
$delete_keys = call_user_func_array('array_merge', $keys);
// Locate all keys that begin with our prefix.
foreach ($delete_keys as $index => $key) {
// If strpos returns 0 (not false) then we have a match.
if (strpos($key, $key_prefix) === 0) {
$mc->delete($key);
}
}
}
return $delete_keys;
}
/*
* Helper function to send memcache commands to a given Memcache Server
*/
function memcache_command($server, $port, $command) {
$s = @fsockopen($server, $port);
if (!$s) {
return die("Cant connect to:" . $server . ":" . $port);
}
fwrite($s, $command . "\r\n");
$buf = "";
while ((!feof($s))) {
$buf .= fgets($s, 256);
// Stat says 'END'.
if (strpos($buf, "END\r\n") !== FALSE) {
break;
}
// Delete says DELETED or NOT_FOUND.
if (strpos($buf, "DELETED\r\n") !== FALSE || strpos($buf, "NOT_FOUND\r\n") !== FALSE) {
break;
}
// Flush_all says ok.
if (strpos($buf, "OK\r\n") !== FALSE) {
break;
}
}
fclose($s);
return ($buf);
}
Answered By - awm Answer Checked By - Terry (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.