DevConf 2015

Memcache

add a note add a note

User Contributed Notes 2 notes

up
0
gabriel dot maybrun at demandmedia dot com
8 months ago
GOTCHA: Recently I was tasked with moving from PECL memcache to PECL memcached and ran into a major problem -- memcache and memcached serialize data differently, meaning that data written with one library can't necessarily be read with the other library.

For example, If you write an object or an array with memcache, it's interpreted as an integer by memcached.  If you write it with memcached, it's interpreted as a string by memcache.

tl;dr - You can't safely switch between memcache and memcached without a either a cache flush or isolated cache environments.

<?php
$memcache
= new Memcache;
$memcacheD = new Memcached;
$memcache->addServer($host);
$memcacheD->addServers($servers);

$checks = array(
   
123,
   
4542.32,
   
'a string',
   
true,
    array(
123, 'string'),
    (object)array(
'key1' => 'value1'),
);
foreach (
$checks as $i => $value) {
    print
"Checking WRITE with Memcache\n";
   
$key = 'cachetest' . $i;
   
$memcache->set($key, $value);
   
usleep(100);
   
$val = $memcache->get($key);
   
$valD = $memcacheD->get($key);
    if (
$val !== $valD) {
        print
"Not compatible!";
       
var_dump(compact('val', 'valD'));
    }

    print
"Checking WRITE with MemcacheD\n";
   
$key = 'cachetest' . $i;
   
$memcacheD->set($key, $value);
   
usleep(100);
   
$val = $memcache->get($key);
   
$valD = $memcacheD->get($key);
    if (
$val !== $valD) {
        print
"Not compatible!";
       
var_dump(compact('val', 'valD'));
    }
}
up
-1
Anonymous
3 months ago
I ran Gabriel's test above and had different results. I did find differences in the objects. For instance:
  'val' => string(7) "4542.32"
  'valD' => double(4542.32)

But, I think this could be resolved. Fairly easily.

The main issue with the test was that one port is used. I ran another instance of memcached on a different port and changed the code slightly.  I used this code and had better success:

$servers = array(array('localserv', 11212));
$memcache = new Memcache;
$memcacheD = new Memcached;
$memcache->addServer('localserv', 11211);
$memcacheD->addServers($servers);
$memcacheD->setOption(Memcached::OPT_BINARY_PROTOCOL, true);

$checks = array(
    123,
    4542.32,
    'a string',
    true,
    array(123, 'string'),
    (object)array('key1' => 'value1'),
);
foreach ($checks as $i => $value) {
    print "Checking WRITE with Memcache\n";
    $key = 'cachetest' . $i;
    $memcache->set($key, $value);
    usleep(100);
    $val = $memcache->get($key);
    $valD = $memcacheD->get($key);
    if ($val !== $valD) {
        print "Not compatible!";
        var_dump(compact('val', 'valD'));
    } else {
        print "WAS COMPAT\n";
    }

    print "Checking WRITE with MemcacheD\n";
    $key = 'cachetest' . $i;
    $memcacheD->set($key, $value);
    usleep(100);
    $val = $memcache->get($key);
    $valD = $memcacheD->get($key);
    if ($val !== $valD) {
        print "Not compatible!";
        var_dump(compact('val', 'valD'));
    } else {
        print "WAS COMPAT\n";
    }
}
To Top