Dani 4,084 The Queen of DaniWeb Administrator Featured Poster Premium Member

This question specifically relates to PHP's Memcached library when specifying a server key and adding multiple keys at once.

Question one: Is it true that PHP's setMultiByKey() doesn't take advantage of the memcached server's native support for setting multiple keys at once, but that the logic is on PHP's side as a simple for loop, setting keys individually?

Question two: Strictly from a performance perspective, in a case when one could expect the keys to already exist on the server more than 90% of the time, which of the following is more efficient?

// Option 1: Setting everything and letting stuff abstracted away decide how to handle it
$items = array(...);
$memcached->setMultiByKey($server_id, $items, 2592000);

// Option 2:    
$items = array(...);
foreach ($items AS $key => $value)
{
    if ($memcached->replaceByKey($server_id, $key, $value, 2592000))
    {
        // Remove it from the array if it was successfully updated
        unset($items[$key]);
    }
}

// For everything not successfully replaced
$memcached->setMultiByKey($server_id, $items, 2592000);

// Option 3
$items = array(...);
foreach ($items AS $key => $value)
{
    if (!$memcached->replaceByKey($server_id, $key, $value, 2592000))
    {
        // It was not successfully replaced, so add it
        $memcached->addByKey($server_id, $key, $value, 2592000))
    }
}

The problem that I'm trying to solve is that I'm very frequently re-setting data that already exists in the cache. This is causing a LOT of premature expirations. After some research, it seems that set() just pushes a new element to the cache whether or not the same key already exists on the server. Either will be fetched until the older one expires. This often means evicting a random item to make room, causing a ton of evictions for no reason. It's my understanding that replace() overwrites the existing element, utilizing the same space in memory.

Unfortunately, there is no addMultiByKey() or replaceMultiByKey(). Therefore, I'm left having to decide if it's more performant using multiple replaces followed by multiple adds for each replace that fails (I'm expecting it to fail 10% of the time), or if it's more perfomant to use multiple replaces followed by a single setMulti for whatever is leftover. In the case where a key does not already exist on the server, are set() and add() equivalent?

My use case does involve a pool of memcached servers over the network. Therefore, whether setMulti() is handled on the Memcached server side or as a series of loops on the PHP web server side does make a difference.

Thanks so much in advance!!