knightly

Blog Archives

Memcached telnet interface commands

I was looking for the list of Memcached telnet commands. And couldn’t find much in the docs. So after some Google searching i finally found the list. And will keep it here for future reference.

So i did a bit of reading while working on a memcache tool in PHP. I found some good documentation on the memcached.org website.

Command Description Example
get Reads a value get mykey
set Set a key unconditionally set mykey 0 60 5
add Add a new key add newkey 0 60 5
replace Overwrite existing key replace key 0 60 5
append Append data to existing key append key 0 60 15
prepend Prepend data to existing key prepend key 0 60 15
incr Increments numerical key value by given number incr mykey 2
decr Decrements numerical key value by given number decr mykey 5
delete Deletes an existing key delete mykey
flush_all Invalidate specific items immediately flush_all
Invalidate all items in n seconds flush_all 900
stats Prints general statistics stats
Prints memory statistics stats slabs
Prints memory statistics stats malloc
Print higher level allocation statistics stats items
stats detail
stats sizes
Resets statistics stats reset
version Prints server version. version
verbosity Increases log level verbosity
quit Terminate telnet session quit

Cache data with Zend Framework and Memcached

Last week i had the chance to work with memcache. Something i hadn’t done before. For caching i mostly rely on APC for bytecode. And file based caching for content. Using memecache extension for PHP and de memcached service gives a whole range of features for caching data. And an easy way to manage all this cached data.

The project i am working on is based on Zend Framework. And there for this post will reflect working with memcache in ZF only. With ZF and memcache it’s possible to do frontend and backend caching. I will focuse on the backend side for now. But will setup the frontend as well.

If you don’t have memcache installed do it now. It’s not that hard. On my debian box it went somethign like this:

$ aptitude install memcached
$ aptitude install php5-memcache

Now a days evrything seems to go automatic. So no need to edit the php.ini or anyhting. To check if PHP loaded the memcache extension you can do:

$ php -m | grep memcache
memcache

Memached is automatically started after install. So let’s check if everything went ok.

$ ps -aux | grep memcached
nobody 20965 0.0 0.5 42900 23072 ? S Jan28 0:01 /usr/bin/memcached -m 64 -p 11211 -u nobody -l 127.0.0.1
root 22393 0.0 0.0 87940 776 pts/0 R+ 12:06 0:00 grep memcached

$ netstat -an | grep 11211
tcp 0 0 127.0.0.1:11211 0.0.0.0:* LISTEN

Looking good. Now it’s time to do some configuration in ZF.

First of the frontend settings. With ‘type’ we set the cache method for the frontend. We chose the standard Core class for this. With ‘lifetime’ we set the time for which a cached entity is valid. The ‘cache_id_prefix’ is a nice way to group for instnace cache data by controller. So just give it a name.

cache.frontend.type = Core
cache.frontend.options.lifetime = 600
cache.frontend.options.automatic_serialization = true
cache.frontend.options.cache_id_prefix = [some string]
cache.frontend.options.cache = true

Now it’s the backends turn to get configured. For ‘type’ we choose Memcached. More types are available. For more info read the ZF manual. The rest of the settings are basic memcached settings like host, port and persitance.

cache.backend.type = Memcached
cache.backend.options.servers.1.host = 127.0.0.1
cache.backend.options.servers.1.port = 11211
cache.backend.options.servers.1.persistent = true
cache.backend.options.servers.1.weight = 1
cache.backend.options.servers.1.timeout = 5
cache.backend.options.servers.1.retry_interval = 15

Finally we can do some PHP code. To get the cache instance setup we add a _initCache() method to the bootstrap class. Inside this method we retrieve the config options by calling getOptions(). And setup the cache object. Which is then stored in the Registry for later use.

protected function _initCache()
{
        $options = $this->getOptions();

        if (isset($options['cache'])) {
            $cache = Zend_Cache::factory(
                $options['cache']['frontend']['type'],
                $options['cache']['backend']['type'],
                $options['cache']['frontend']['options'],
                $options['cache']['backend']['options']
            );

            Zend_Registry::set('cache', $cache);
            return $cache;
        }
}

That’s all set. I used the caching for some REST service responses. So i will stick to that in this post as well. The class has a method for adding a cache object.

public function setCache(Zend_Cache_Core $cache) {
    $this->cache = $cache;
}

So fetching the cache instance and passing it to the REST client will look something like this:

$cache = Zend_Registry::get('cache');
$cache->setLifetime(86400);

$client = new Client();
$client->setCache($cache);

The first thing we do inside the calling method is set a unique key for the cache entry.

$cache_id = 'getPage_' . $this->getDomain()
            . $this->getPageName()
            . $this->getCountry();

Then we check if the cache object is set. If that’s the case we check to see if the unique key is already available in the cache.

if (!isset($this->cache) || !($ret = $this->cache->load($cache_id))) {

If a value is returned from the cahce we will return it. If not then we will do the webservice call and store the return data in cache.

 $ret = $this->restClient->call('getPage', array());

if (isset($this->cache)) {
    $this->cache->save($ret, $cache_id);
}

The complete method looks something like this.

protected function getPageFromWebservice()
{
        $cache_id = 'getPage_' . $this->getDomain()
            . $this->getPageName()
            . $this->getCountry();

        if (!isset($this->cache) || !($ret = $this->cache->load($cache_id))) {
            $ret = $this->restClient->call('getPage', array());

            if (isset($this->cache)) {
                $this->cache->save($ret, $cache_id);
            }
        }
        return $ret;
}

That’s all. It’s pretty basic stuff. But so cool!

Stop ACTA