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
Install via a *nix package manager eg. apt, yum, rpm etc. Start your memcache servers:
/usr/local/bin/memcached -u root -d -m 1024 -l 0.0.0.0 -p 11211
Add one more to the pool: (this will make sense later. promise)
/usr/local/bin/memcached -u root -d -m 1024 -l 0.0.0.0 -p 11212
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
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
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.
// 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.
A crude test
This code can be appended to the php snippet from above
echo â€œSession save_handler is: â€œ.ini_get(â€session.save_handlerâ€).â€
echo â€œSession save_path is: â€œ.ini_get(â€session.save_pathâ€).â€
echo â€œBleh is already set: â€œ.$_SESSION[‘bleh’].â€
$_SESSION[‘bleh’] = â€˜bwahahhaâ€™;
echo â€˜Bleh has been set with: â€˜.$_SESSION[‘bleh’].â€
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.
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.
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.
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.
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?