Check if a key exists in Memcache

前端 未结 11 2321
无人共我
无人共我 2021-02-12 15:17

How do I check in PHP if a value is stored in Memcache without fetching it? I don\'t like fetching it because the values I have set are all 1MB in size and after I fetch it, I h

相关标签:
11条回答
  • 2021-02-12 15:42

    I wonder why Memcached has no special method for it. Here is what I came down to after some considerations:

    function has($key)
    {
        $m->get($key)
    
        return \Memcached::RES_NOTFOUND !== $m->getResultCode();
    }
    
    0 讨论(0)
  • 2021-02-12 15:45

    memcached now has the cas command. you can use it with a cas unique as 0 to get the EXISTS or NOT_FOUND responses:

    $ telnet localhost 11211
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    set hello 0 0 5
    12345
    STORED
    gets hello
    VALUE hello 0 5 6743
    12345
    END
    cas hello 0 0 0 0
    
    EXISTS
    cas foo 0 0 0 0 
    
    NOT_FOUND
    

    In the transcript above, I first use the set command to set a key hello with value 12345. Then gets it back, which also returned a cas unique 6743. Then I try to use cas command to replace the value with nothing, but because the cas unique I used is 0, I got back EXISTS error.

    Finally I try to use cas to set a key foo that doesn't exist and get back NOT_FOUND error.

    Because memcached uses a global incrementing value for cas unique, using 0 is safe that it's not valid for the item you are trying to set and you would get back EXISTS error if it does exist.

    Sorry, not familiar with php's memcache client to put it in php code.

    0 讨论(0)
  • 2021-02-12 15:47

    I needed a reliable test to know wether to use memcache Set or memcache replace.

    This is what I ended up with.

    Another option would be to set up a network socket to the memcache query, but in the end it would end up doing the same and this connection already exists, saving me the overhead of making and maintaining another connection like in Joel Chen's answer.

    $key = 'test';
    $value = 'foobarbaz';
    /**
     * Intricate dance to test if key exists.
     * If it doesn't exist flags will remain a boolean and we need to use the method set.
     * If it does exist it'll be set to integer indicating the compression and what not, then we need to use replace.
     */
    $storageFlag = (is_null($value) || is_bool($value) || is_int($value) || is_float($value) ? false : MEMCACHE_COMPRESSED);
    $flags = false;
    $memcache->get($key, $flags);
    if(false === $flags) {
        $memcache->set($key, $value, storageFlag  , $minutes);
    }
    else {
        $memcache->replace($key, $value, storageFlag, $minutes);
    }
    

    Now if you have "large data" the solution is fairly simple. Use a second key in cojoin that contains something simple like an integer to check. Always use them together and you have no issues.

    $key = 'test';
    $value = 'foobarbaz';
    
    $storageFlag = (is_null($value) || is_bool($value) || is_int($value) || is_float($value) ? false : MEMCACHE_COMPRESSED);
    $flags = false;
    $exist_key = $key.'_exists';
    
    $memcache->get($exist_key, $flags);
    if(false === $flags) {
        $memcache->set($key, $value, storageFlag  , $minutes);
        $memcache->set($exist_key, 42, false  , $minutes);
    }
    else {
        $memcache->replace($key, $value, storageFlag, $minutes);
        $memcache->replace($exist_key, 42, false  , $minutes);
    }
    
    0 讨论(0)
  • 2021-02-12 15:49

    Simply not possible, It is not possible to check for only key exists or not. Better you create a separate key with true/false values to check for existence of keys

    0 讨论(0)
  • 2021-02-12 15:56

    I've solved this by using Memcached::append. I try appending value NULL and if it returns TRUE, it means the key exists. If it returns FALSE it means the key doesn't exist. If the key exist it will also put it on top of LRU list.

    0 讨论(0)
提交回复
热议问题