Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memcache - values deleted from memcache reappearing

Tags:

php

memcached

I'm using memcache to store Zend_Config (and other values) - I'm setting the values as follows:

$memcache = new Memcache();
...

if (!$config = $memcache->get($memcache->unique_key.APPLICATION_DOMAIN."#config"))
{
    ...
    $memcache->set($memcache->unique_key.APPLICATION_DOMAIN."#config", $config);
}

I'm deleting values as follows:

$memcache->delete($key);

After I delete the values from memcache, it properly displays in the same connection as deleted - calling $memcache->get($key) properly gives me NULL. However, when I refresh the script (and establish new connection with memcache) the data pops back in, as if the memcache state weren't updated. I've tried using replace instead (with some specific value), to the same effect - the value doesn't update.

Calling $memcache->flush() works, and removes everything from memcache, however I want to delete specific keys.

On the manual page there's a cryptic message from 5 years ago about incompatibilities between PECL versions and memcached (but that's from 5 years ago). Can somebody explain to me what might be happening?

I'm using memcached 1.4.21 with memcache (PECL) 3.0.8 on PHP 5.6

like image 501
eithed Avatar asked Jul 08 '16 16:07

eithed


People also ask

How do I delete Memcache?

Memcached::delete() deletes the key from the server. The time parameter is the amount of time in seconds (or Unix time until which) the client wishes the server to refuse add and replace commands for this key.

What happens when memcache is full?

First, when memcached gets full, it will start removing items from the cache using the Least Recently Used algorithm. Second, you can have multiple instances of memcached running, adding them gets complicated because it will change the hashing algorithm used to determine which cache the data is in.


1 Answers

The issue stems from usage of this:

$list = array();
$allSlabs = $memcache->getExtendedStats('slabs');

foreach ($allSlabs as $server => $slabs)
    foreach ($slabs as $slabId => $slabMeta)
        foreach ($memcache->getExtendedStats('cachedump', (int) $slabId) as $entries)
            if (!empty($entries))
                foreach ($entries as $key => $entry)
                    if (strpos($key, $memcache->unique_key) === 0)
                    {
                        $value = $memcache->get($key);
                        $list[$key] = is_string($value) && unserialize($value) ? unserialize($value) : $value;
                    }

(you'll notice that it's not included in my original query, as it doesn't do anything, but lists keys / values stored in memcached)

The problem with this functionality is that it apparently, silently, causes the memcached to become readonly. While the values that are served on consequent calls of the function are updated (as, I think, they're retrieved from local memory), the values in memcached service are not.

This behaviour affects current up-to-date version of memcached - the breaking behaviour was introduced in memcache (2.2.x)

I'll keep bounty open if somebody feels like to investigate this behaviour

like image 79
eithed Avatar answered Oct 04 '22 16:10

eithed