According to memcached is a distributed object memory caching system. It can be used to set and get data by keys by any application that supports sockets.

As a website security consultant I advise you to ensure that your memcache server runs on 127.0.0.1 only and that you secure your server. Anyone with access to the server can telnet to the server’s local interface and get/set your memcache data.

I’ve used memcached for a number of PHP/MySQL projects, where I want greater cache control on database queries, than just relying on MySQL’s inbuilt caching abilities.

Now, whilst memcached should not be used to mask bad database design and optimization, or badly written SQL queries, it can help dramatically with queries that simply take a long time and have already been optimized as far as possible.

Assume that you had a simple database query wrapper:

function db_getrows($query)
{

$rows = Array();
$resource = mysql_query($query);
while ($rows[] = mysql_fetch_object($resource))
{

//do nothing

}
return $rows;

}

If you have no idea what queries are going to get passed to this, but simply want to cache all SELECT output, then modify as follows:

function db_getrows($query)
{

$rows = Array();
//Get the MD5 hash of the query, which we can use to identify it:
$hash = md5($query);
$memcache_obj = memcache_connect(“localhost”, 11211); //connect to memcached
$mem_get = memcache_get($memcache_obj, $hash); //If we had this query key stored in memcache, $mem_get will now contain the data, otherwise, it will be empty.

if (empty($mem_get))
{

$resource = mysql_query($query);
while ($rows[] = mysql_fetch_object($resource))
{

//do nothing

}
memcache_add($memcache_obj, $hash, serialize($rows), false, (60*60)); //add it to memcache for next time, have it expire in 1 hour (60*60 seconds)

} else {

$rows = unserialize($mem_get);

}
return $rows;

}

What will happen now, is that when a query is provided, we take the MD5 sum of that query. We then check to see if we have that query response in memcache already. If so, great, unserialize it and return it. If not, run the query, get the data, and add it to memcache with an expiry time of 1 hour.

Any queries to memcache will of course bypass the database alltogether therefore alleviating the load. Your only consideration is what to cache and the expiry time. If you cache the output of a SELECT query on say, the number of posts on your forum, it may not just keep that out of date for an hour, but could infact cause erroneous data to be inserted by your forum into your database. In that case, you can take a look through the code and find any instances where your forum post count may be updated, and add memcache_delete($memcache_obj, ‘key_to_delete’, 10); which will automatically delete ‘key_to_delete’ after 10 seconds.