Php Session clustering with memcache

Rate this post

Just saving an old article from oblivion:

You need php session-clustering and you need it done yesterday. The project is at risk. The suits are breathing down your neck and monitoring your every tweet. Memcache to the rescue

Installing memcached

Install via a *nix package manager eg. apt, yum, rpm etc. Start your memcache servers:

[text]
/usr/local/bin/memcached -u root -d -m 1024 -l 0.0.0.0 -p 11211
[/text]

Add one more to the pool: (this will make sense later. promise)

[text]
/usr/local/bin/memcached -u root -d -m 1024 -l 0.0.0.0 -p 11212
[/text]

Note: the port number differs for the second memcached daemon.

Installing memcache extension with “session feature”

PHP “talks” to a memcache server via the memcache extension but you already knew that. Something less known is that when installing this extension you can enable/disable the extension’s session.save_handler feature.

[php]qbook:Locate quinton$ sudo pecl install memcache
Password:
downloading memcache-2.2.5.tgz …
Starting to download memcache-2.2.5.tgz (35,981 bytes)
….done: 35,981 bytes
11 source files, building
running: phpize
Configuring for:
PHP Api Version: 20041225
Zend Module Api No: 20060613
Zend Extension Api No: 220060519
1. Enable memcache session handler support? : yes[/php]

Choose “yes”. You can now configure php to use memcache as its session store.

Configuring the memcache session store

ext/memcache introduces new directives to the php.ini. In this post I’ll use ini_set() within a php script so you can just copy-and-paste to try it out yourself. In your production environment you’ll prolly want these directives inside your php.ini and/or apache vhost. You decide.

[php]<?php

// firstly, override the default session save_handler like this
ini_set(’session.save_handler’, “memcache”); // PHP_INI_ALL Supported since memcache 2.1.2

// now tell php where to store the sessions. two memcache servers specified here. more bout that later
ini_set(’session.save_path’, “tcp://localhost:11211, tcp://localhost:11212″); // PHP_INI_ALL Supported since memcache 2.1.2

// getting interesting. if primary server is down talk to the others in the server pool
ini_set(’memcache.allow_failover’, “1″); // PHP_INI_ALL Available since memcache 2.0.2.

// more tweaking stuff follows here

// may want to adjust this
ini_set(’memcache.max_failover_attempts’, “20″); // PHP_INI_ALL Available since memcache 2.1.0.

ini_set(’memcache.default_port’, “11211″); // PHP_INI_ALL Available since memcache 2.0.2.

ini_set(’memcache.chunk_size’, “8192″); // PHP_INI_ALL Available since memcache 2.0.2.

ini_set(’memcache.hash_strategy’, “standard”); // PHP_INI_ALL Available since memcache 2.2.0.

ini_set(’memcache.hash_function’, “crc32″); // PHP_INI_ALL Available since memcache 2.2.0.

?>[/php]

A crude test

This code can be appended to the php snippet from above

[php]<?php

session_start();

echo “Session save_handler is: “.ini_get(”session.save_handler”).”
“;
echo “Session save_path is: “.ini_get(”session.save_path”).”
“;

if(isset($_SESSION[‘bleh’]))
{
echo “Bleh is already set: “.$_SESSION[‘bleh’].”
“;
}
else
{
$_SESSION[‘bleh’] = ‘bwahahha’;
echo ‘Bleh has been set with: ‘.$_SESSION[‘bleh’].”
“;
}

?>

[/php]
Where’s the clustering you ask

Well, truth be told there isn’t any. What we have so far is a memcache pool consisting of 2 servers. PHP is configured to write to the pool. PHP reads/writes to the server pool in order specified by “session.save_path” ini directive. For reads PHP will request a cache object by key from the pool. Because “failover” is enabled PHP will query the pool of memcache servers one-by-one until the request is fulfilled. Every silver lining has a cloud.

Fragmentation

In the event of a memcache server crash, fragmentation will occur. Therefore the pool will have an identical cache and its exceptionally hard to tell which keys each memcache server is storing. When a memcache daemon crashes it loses all data. Memory, by nature, is volatile. You have been warned.

Replication

This method is most commonly refered to as client-side replication BUT is better described as redundancy. There is a method of achieving server-side replication (think mysql replication). AFAIK repcached is the only available patch of its kind. I would like to try it but haven’t had the opportunity. Its a long story.

Summary

Memcache-based session save_handler is a quick-win but its NOT scalable. As your server farm grows the cost of maintaining and managing this solution is complexity. Also, consider the implications of managing a php.ini per web server and the repercussions of the failover feature. Nasty. However, there is good news. A libmemcached-based extension is on the way.

Getting real

If you have more time to spare take the safer option ie. storing sessions in a database. You could write a custom session save_handler or just use Zend framework’s Zend_Session_SaveHandler_DbTable. What could be easier?

Lascia un Commento

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *

È possibile utilizzare questi tag ed attributi XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">