I need to replicate memcached to another key value system (couchbase). How can I query the contents of a memcached server to get a list of what is in there so that I can copy it over?
Asked
Active
Viewed 1.7k times
5 Answers
13
All these solutions for Memcache so here's for Memcached
function getMemcachedKeys($host = '127.0.0.1', $port = 11211)
{
$mem = @fsockopen($host, $port);
if ($mem === FALSE) return -1;
// retrieve distinct slab
$r = @fwrite($mem, 'stats items' . chr(10));
if ($r === FALSE) return -2;
$slab = array();
while (($l = @fgets($mem, 1024)) !== FALSE) {
// sortie ?
$l = trim($l);
if ($l == 'END') break;
$m = array();
// <STAT items:22:evicted_nonzero 0>
$r = preg_match('/^STAT\sitems\:(\d+)\:/', $l, $m);
if ($r != 1) return -3;
$a_slab = $m[1];
if (!array_key_exists($a_slab, $slab)) $slab[$a_slab] = array();
}
// recuperer les items
reset($slab);
foreach ($slab AS $a_slab_key => &$a_slab) {
$r = @fwrite($mem, 'stats cachedump ' . $a_slab_key . ' 100' . chr(10));
if ($r === FALSE) return -4;
while (($l = @fgets($mem, 1024)) !== FALSE) {
// sortie ?
$l = trim($l);
if ($l == 'END') break;
$m = array();
// ITEM 42 [118 b; 1354717302 s]
$r = preg_match('/^ITEM\s([^\s]+)\s/', $l, $m);
if ($r != 1) return -5;
$a_key = $m[1];
$a_slab[] = $a_key;
}
}
// close
@fclose($mem);
unset($mem);
// transform it;
$keys = array();
reset($slab);
foreach ($slab AS &$a_slab) {
reset($a_slab);
foreach ($a_slab AS &$a_key) $keys[] = $a_key;
}
unset($slab);
return $keys;
}

Maduka Jayalath
- 1,338
- 1
- 14
- 15
-
1This is the best answer currently even though people haven't voted for it yet; the question asker was asking about Memcached with a 'd'. I don't know why Mark Baker's answer got so many upvotes. – Ryan Apr 04 '17 at 20:47
-
1
-
The `stats cachedump` returns INCOMPLETE data (only returns COLD items, returns at most 2MB of data, only returns first 100 items per slab in the above code), does LOCK up the whole cache while it runs, is periodically discussed to be removed from the codebase (as its for small-testbed-debugging purposes only). `lru_crawler` sounds more-promising: https://stackoverflow.com/a/60604336/2809546 – Vlad Dec 19 '22 at 17:15
10
memcache >= 2.0.0
function getMemcacheKeys() {
$memcache = new Memcache;
$memcache->connect('127.0.0.1', 11211)
or die ("Could not connect to memcache server");
$list = array();
$allSlabs = $memcache->getExtendedStats('slabs');
$items = $memcache->getExtendedStats('items');
foreach($allSlabs as $server => $slabs) {
foreach($slabs AS $slabId => $slabMeta) {
$cdump = $memcache->getExtendedStats('cachedump',(int)$slabId);
foreach($cdump AS $keys => $arrVal) {
if (!is_array($arrVal)) continue;
foreach($arrVal AS $k => $v) {
echo $k .'<br>';
}
}
}
}
}

Mark Baker
- 209,507
- 32
- 346
- 385
-
3I just want to note here that while this works cachedump is really meant for memcached debugging purposes and isn't intended to be used like this. Future versions of memcached also might not support cachedump. (See comment 8 here from one of the core memcached contributors http://code.google.com/p/memcached/issues/detail?id=187) – mikewied Mar 25 '12 at 03:36
-
2Cachedump does not seem to get all of the keys (I've been trying to do this, and then came across this link): http://code.google.com/p/memcached/wiki/NewProgrammingFAQ – jonderry Dec 19 '12 at 00:54
-
one small but big difference which worked for me was the **limit** parameter in `getExtendedStats` function, default value is _just_ 100. update: `$cdump = $memcache->getExtendedStats('cachedump',(int)$slabId,100000000);` – matija Jul 07 '16 at 10:00
-
This function is faulty as it makes the memcache readonly, at least with current version of memcache PECL (3.0.8) and memcached (1.4.21) – eithed Jul 28 '16 at 15:16
-
@matija you can pass 0 as the final parameter to remove the limit entirely – Gruffy Jan 20 '17 at 15:08
-
That's memcache, the question is for memcached. They are different libraries. – Apollo May 18 '17 at 09:36
1
- According to the report https://www.php.net/manual/en/memcached.getallkeys.php#123793 function
Memcached::getAllKeys
does not works since memcached 1.4.23. Also it no guaranty return of all keys. - Code provided by @mark-baker, @maduka-jayalath and others based on
stats cachedump
has limitation and does not return all keys in case you have millions of keys in memcache. Also it have performance influence on memcache server.
There is library that allows to iterate between all memcache keys asynchronously without performance influence: https://github.com/qmegas/memcache-search It even not require any memcache extension to be installed.

Megas
- 81
- 1
- 9
-
1Did you mean "*`Memcached::getAllKeys` does **NOT** work*" since 1.4.23? That's what the link you reference says. – Don't Panic Dec 20 '22 at 22:45
-
1
-1
As per the documentation:
https://www.php.net/manual/en/memcached.getallkeys.php
PECL memcached >= 2.0.0
$memcached->getAllKeys();

WebDevNerdStuff
- 391
- 1
- 4
- 13
-2
Thanks for the sample code
Here is how to remove a specific key or multiple keys
I am using a helper class to remove the cache so you have to give the function a reference to the memcache connection
public static function removePriceCache(&$memcache, &$cacheAvailable) {
if ($cacheAvailable == true) {
$list = array();
$allSlabs = $memcache->getExtendedStats('slabs');
$items = $memcache->getExtendedStats('items');
foreach ($allSlabs as $server => $slabs) {
foreach ($slabs AS $slabId => $slabMeta) {
$cdump = $memcache->getExtendedStats('cachedump', (int) $slabId);
foreach ($cdump AS $keys => $arrVal) {
if (!is_array($arrVal))
continue;
foreach ($arrVal as $k => $v) {
//echo $k . '<br>';
if (stripos($k, "Price") !== false) {
$memcache->delete($k);
}
}
}
}
}
}
}
This will delete all the keys that have the word 'Price' in it..

webmaster
- 1,960
- 24
- 29