Lorna Mitchell

Memcache is a tool which can cache objects in memory – and is often used for speeding up dynamic web applications. PHP has a built-in module for working with memcache, and its a simple and convenient way of introducing caching to your application.

PHP has a PECL module for talking to memcached – look up how to install for your system, but be aware that it isn't bundled. It's a good module to include on your system however, quite a few apps will take advantage of it where available.

Caching Theory

A cache is like a temporary storage, like saying “remember toothpaste” to your 4-year-old when you head out to the shops. Then when you get there “What was I supposed to remember?” And get the answer back. The main difference is, memcache will actually give you back exactly what you gave it and not tell you “lollipops” in a hopeful manner instead!

Caching code in general will usually look something like this:

function selectUserById($user_id)
{
    if this user exists in cache {
        $user = user object from cache
    } else {
        $user = retrieve the user from the database store $user in cache
    }
}

Working with Memcache

Memcache is object storage, objects are stored in a serialised manner in RAM, with a unique key to identify them. This means that you need a unique string to identify any object you may store in the cache. Primary keys work fine but look out for when you are storing multiple types of object in there - <object_type>_<primary_key> probably works better in that scenario.

The storage persists as long as the machine is on – a reboot empties the RAM and therefore clears the cache. You can also set how long a cached object is valid for. After that time, memcache will return false when you request your object and your code will fall through to its usual retrieval process.

Cache Code

Getting up and running with memcache is so easy that it’s one of those things you sit down to read up on and ten minutes later you realise you've actually already done it. Once you have memcache installed and set up with PHP, all you need is to create a memcache object to use in your application. Here's the code for mine:

$cache = new Memcache();
$cache->addServer('localhost') or die('Memcache not found');

To work with distributed memcaches, just make the call to addServer() multiple times. It is also possible to set a surprisingly large number of options with this function, including which port should be used, some connectivity settings, and even a weighting to say how likely this server is to be selected to store something. It’s a very powerful and flexible tool and in this tutorial we're only really looking at the top layer – but do read the manual pages and be aware that these options exist.

In PHP, the code you need to work with memcache is really minimal and wraps nicely around existing code without too much hassle. Consider my getUserById() function from earlier, here it is before I added caching:

function getUserById($user_id)
{
    // query the database for the user information
    $sql    = "SELECT * FROM users WHERE user_id = :user_id";
    $stmt   = $this->_db->prepare($sql);
    $result = $stmt->execute(array(":user_id" => $user_id));
    $user   = $stmt->fetch(PDO::FETCH_ASSOC);
 
    // return the user
    return $user;
}

We can wrap caching code around this, to firstly try to pull the object from the cache, and failing that to grab the object from the database and put it in the cache for next time

function getUserById($user_id)
{
    // see if we already have this user in the cache
    if($this->_cache->get('user'.$user_id) {
        // found the user – return it
        return $this->_cache->get('user'.$user_id);
    }
 
    // query the database for the user information
    $sql     = "SELECT * FROM users WHERE user_id = :user_id";
    $stmt    = $this->_db->prepare($sql);
    $results = $stmt->execute(array(":user_id" => $user_id));
    $user    = $stmt->fetch(PDO::FETCH_ASSOC);
 
    // save the results for next time
    $this->_cache->add('user'.$user_id, $user);
 
    // return the user
    return $user;
}

All we've added here is a small conditional at the top of the function to immediately return the information if it exists in the cache – in this case the rest of the function doesn't need to be executed. Finally, just before returning from this function, we've added a line to store the user information in the cache for faster access next time.

Cache Size and Persistence

With an infinitely large RAM storage area for memcache to live on, theoroetically you could cache all the information in your application and just access it from there. In reality though there are limitations and knowing how memcache works will help you to get the most out of the tool.

When you add something to memcache, you can optionally set an expiry for it – stating how many seconds this cache is valid for. If this isn't specified then the object will persist unless it gets pushed out (more about that later). When picking expiry times, consider how often the information changes and could get outdated – if it’s very frequently, then consider not using the cache at all as this space could be better used storing other data.

When the cache becomes full, memcache will perform some magic to keep the data you are using the most. Things which aren't used often will eventually drop out of the space to be replaced with newer data. It can be tricky to work out how much cache is needed for a particular application – really the only way to get this right is to do some benchmarking and look at how the performance varies with cache size.

Cache Applications

Caching is really useful for getting around bottlenecks such as having a database on a different server or a narrow pipe to a filestore. It is even more useful when that information doesn't change often – or if it doesn't matter too much whether the change is reflected straight away.

The example shown in this article was oversimplified – but I've used something very similar in a situation where third-party sites were pulling profile information from a shared central server and checking user validity with every user request. Users typically log in to one of the sites, browse around (sending a whole bunch of requests for their same profile information) and then move away – implementing memcache speeded up those subsequent requests hugely, and when they navigate away, their data either expires or gets pushed out of the cache by newer material.

Caching can also be useful for session data in PHP – so useful in fact that the memcache module comes with built-in support for storing session data in a cache. With the memcache module enabled, the php.ini directive session.save_handler can take the value "memcache" to store session data in memory rather than in files (the default option) or in the database.

Memcache as a Tool

Memcache can be a big help but its not the silver bullet that will solve all performance problems. When added in the right place, it can produce very impressive results – especially for high-traffic applications. Its a great tool to have in the toolbox, and its really simple to get started with, so next time you need to improve the performance of an application, bear it in mind.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Plus

17 Responses

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

  1. Great article to start off the techportal. Just subscribed to feed now :-)

  2. Nice article :-)

    A great start to the techportal. I'll be looking forward to future articles!

  3. Zolgan said

    Nice Read. Hope to see more of those bits! Anyway, why haven't you provided a strategy pattern here?

  4. Nice one.

    Just one thing, to keep the article coherent: the function "getUserById" is actually called "selectUserById" in its first occurrence.

  5. Memcached is fast, and it use distributed system. So, we can use memcached separately from web server.

  6. Jonathan Nieto said

    Nice article about Memcached, it make me clear some doubts about it, thx.

  7. Nice article! I did a presentation on this subject at BarCamp Brighton last year. For those who are interested: get it here. It also includes some nice demo code.

    Good luck with this portal guys! I'll be keeping an eye on it!

  8. Nice introduction to memcache. I haven't worked with it yet but I bet there will be some tricks when caching object holding all kinds of references?
    (I suppose similar to storing objects in sessions really)

  9. Added to TUTlist. What a great tutorial, please keep 'em comming!

  10. Jack Indigo said

    What do I do when I have 3 web nodes and one database server these all connect with? I have to be careful about how I implement memcached because a user might come to any one of those web nodes on each click, depending on how the router or reverse proxy is setup for the website. Depending on what you are caching, this could break the app.

    Memcache has its fantastic uses, but this must be considered as well.

  11. Not bad to start with a Memcache )

Continuing the Discussion

  1. techPortal is ALIVE! | Postcards From My Life linked to this post on February 16, 2009

    [...] by, give us a look. To kick things off we’ve got a good article on memcached written by my good friend [...]

  2. Ibuildings Blog linked to this post on February 16, 2009

    The launch of techPortal...

    A little over 2 years ago we started our company blog, mainly to share our experiences and show off cool stuff we were doing. By now, it has become the most popular area of our website, and looking back I can see we have had a nice mix of technical art...

  3. echo “techPortal”; — Domus Neminis linked to this post on February 16, 2009

    [...] The editor in chief of techPortal is Cal Evans, and the first technical post of the blog is by Lorna Mitchell: Getting Started with Memcached. [...]

  4. techPortal - new PHP developer resource - techPortal linked to this post on February 19, 2009

    [...] also very excited on a personal level since I’m already published on the site! My article Getting Started with Memcached is my first contribution to this new venture and I’m looking forward to seeing what else will [...]

  5. abcphp.com linked to this post on March 11, 2009

    Getting Started with Memcached...

    Memcache is a tool which can cache objects in memory – and is often used for speeding up dynamic web applications. PHP has a built-in module for working with memcache, and its a simple and convenient way of introducing caching to your application....

  6. Getting Started with Memcache | ineedtutorials.com linked to this post on May 12, 2009

    [...] Link: Getting Started with Memcache [...]

Some HTML is OK

(required)

(required, but never shared)

or, reply to this post via trackback.