Lorna Mitchell

Earlier in the year, a new memcache extension was released for PHP by Andrei Zmievski, Core PHP Developer and Open Source Fellow at Digg.com. The extension is for dealing with memcache from PHP, and is called memcached (not to be confused with the existing extension, “memcache”). The idea behind the new extension is to leverage the functionality contained libmemcached – a solution which has been widely adopted across many scripting communities and beyond. The extension is available in PECL and has lots of shiny new functionality. This article looks at how to obtain and work with the new extension, and also shows off a couple of the new features it includes.

Installing Memcached

Memcached is available in PECL, so is straightforward to install and use. For me (on Ubuntu), I simply typed:

sudo pecl install memcached-beta

The “-beta” on the end is to tell pecl that its OK for it to grab a package not marked as stable – obviously once the package is marked as stable, this won’t be needed.

Migrating to Memcached

The new extension isn’t designed to have an identical API to the old one, so if you’re already using memcache there is no guarantee of being able to perform a straight swap. That said, I did exactly that with the example in my “Getting Started with Memcache” article, and it worked completely as expected with the only adjustmen being that addServer now requires the port number to connect.

In an ideal world, it would be possible to write a new caching class, swap out your old one, re-run your test suite and just move on – however this is the real world, not the ideal world, and I’m sure the path won’t be so smooth for everyone. Bear in mind though that you can initialise both extensions to use the same memcache storage, so its perfectly possible to migrate functionality across bit-by-bit.

Features

This extension uses the improved functionality in the libmemcached library and, as such, a lot of the improvements are behind-the-scenes rather than something that users can clearly see. In particular there is much better support for working with multiple memcache servers, with grouping and so on – and all the connection-handling is done in libmemcached so there is much less for PHP to handle. There is also a raft of new features, so take a look at the manual for a full list but I’m going to run through a couple of my favourites in detail.

New Feature: getmulti

Allows the retrieval of multiple entries from the memcache server. This is really useful where you know you need a list of things and don’t want to have to make so many round trips. Its also pretty straightforward to do – consider this example, which extends the examples in the previous article, where we had a single user. This user now has a property called “friends” which contains an array of the ids of users they are friends with:

1
2
3
4
5
6
7
function getFriends() {
    $friend_items = array();
    foreach($this->friends as $f) {
        $friend_items[] = $this->_cache->get('user'.$f);
    }
    return $friend_items;
}

Rather than doing this repeatedly, we can send a single request over to the memcache server to give us all the data we need with the getmulti method.

1
2
3
4
5
6
7
function getFriends() {
    $friend_list = array();
    foreach($this->friends as $f) {
        $friend_list[] = 'user'.$f;
    }
    return $this->_cache->getmulti($friend_list);
}

The return value from this second function is identical to the return from the first version – the only difference is that we need only hit the memcache server a single time to get all the information rather than once per friend. As these data sets get larger, the benefit of techniques like this improve.

New Feature: cas (compare and swap)

This a neat function which performs the same action as replace – but it first checks whether the item has changed since it was last read by the current client. This protects against multiple updates coming in from different places. In order for this functionality to work, a system of tokens is provided. The tokens change every time an entry is written, and it is optional to retrieve this value when operating on an item. For example if the user editing their profile, and we want to be sure it didn’t change in the mean time, we might add a little check in:

1
2
3
4
5
6
7
8
// get user profile
$user = $this->_cache->get('user1');
 
// make a change and store new version
$user['email'] = 'lorna@example.com';
$stored = $this->_cache->set('user1',$user);
 
echo $stored; // displays 'true'

This is fine so long as nothing else also updated the record stored at this key in the intervening period. For high-traffic sites, or situations where many users might be causing changes to the same data, this is a big issue. We can make a pseudo-atomic update by using the compare-and-swap functionality that the memcached functionality provides (health warning: This requires memcached 1.2.4 or later, some distros are older than this – for example Ubuntu Jaunty Jackalope only has 1.2.2 although the Karmic Koala version will be 1.2.8).

The compare-and-swap works on a token basis. When you retrieve the information from the cache, you also ask for a token. This token value changes every time the record is updated. When you write your next value back, you also supply the token from the get operation and the data is only stored when the token matches the current value – so you don’t unwittingly overwrite existing data.

1
2
3
4
5
6
7
8
// get user profile
$user = $this->_cache->get('user1', null, $token);
 
// make a change and store new version
$user['email'] = 'lorna@example.com';
$stored = $this->_cache->cas($token, 'user1', $user);
 
echo $stored; // displays 'true' if nothing else changed the record; false otherwise

That final $stored value will be false if the record has changed since we retrived it, at this point it might be appropriate to retrieve a new copy of the data and work with that or take some other evasive action, depending on the context of your application.

In Conclusion

The development of the functionality around memcache has been moving on quite a bit – and having an extension for PHP which allows us to work so easily with these features is a great thing. Although the extension is currently in beta, it is shaping up nicely and is well worth a look for anyone working with memcache or looking to begin to work with it. I think we’ll see this being adopted pretty quickly as even without the additional functionality, its performance is an improvement on the existing extension.

Sharing links:
  • email
  • Twitter
  • Facebook
  • Digg
  • StumbleUpon
  • del.icio.us
  • LinkedIn
  • Technorati
  • DZone

11 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Hi Lorna,

    Thanks for bringing the information to us :)

    If you could also give a hint as where to find the actual system library libmemcached that would be great.
    I’m having trouble finding packages in the official repositories for both Debian and RHAS 5.

    Thanks,
    Steven

  2. Steven: great question :) You can find the library here: http://tangent.org/552/libmemcached.html

  3. Nice article. compare and swap would of been useful for a bug I was dealing with a few weeks ago :)

    One question though, how is getmulti() different from get(array $keys) from the Memcache extension? It appears to do the same thing.

  4. Che: That’s another great question :) As I understand it, the functionality of getmulti is the same as passing the array to the gets, from a user point of view.

  5. Chintan said

    Thanks Lorna,

    Very nice and useful class. before this I haven’t used memcache, now I know and it’s good to increase performance.

Continuing the Discussion

  1. abcphp.com linked to this post on June 22, 2009

    New Memcached Extension for PHP…

    Earlier in the year, a new memcache extension was released for PHP by Andrei Zmievski, Core PHP Developer and Open Source Fellow at Digg.com. The extension is for dealing with memcache from PHP, and is called memcached (not to be confused with the exis…

  2. LornaJane linked to this post on June 22, 2009

    Memcache Follow-Up Article on Techportal…

    Today techportal published a new article of mine on their site – New Memcached Extension for PHP. Its a sequel to the article I wrote for them earlier in the year entitled Getting Started with Memcache. At the same time I wrote that first article, An…

  3. Ibuildings techPortal: New Memcached Extension for PHP | Webs Developer linked to this post on June 22, 2009

    [...] Ibuildings techPortal website has posted a new article from Lorna Mitchell looking at the new and improved memcached extension (as most recently updated [...]

  4. MySQL Left Join « Programming Tips linked to this post on June 23, 2009

    [...] New Memcached Extension for PHP – techPortal [...]

  5. 網站製作學習誌 » [Web] 連結分享 linked to this post on July 3, 2009

    [...] New Memcached Extension for PHP [...]

  6. Memcache Follow-Up Article on Techportal – techPortal linked to this post on July 8, 2009

    [...] techportal published a new article of mine on their site – New Memcached Extension for PHP. Its a sequel to the article I wrote for them earlier in the year entitled Getting Started with [...]