PHP on several servers with session-sharing

load balancingmemcachedPHPredis

there's certanly other threads about this, but I have one more question.

We are about to scale the website at work to have more than one server. And we need to share the sessions between the servers.

We have been looking into different solutions, one in memcached and use Memcached as sessionhandler in PHP. That will probably work.

And the idea would be to run memcached on every machine and let all webservers access all other servers memcached servers, and then we have shared sessions between the machines, yay. (we have no resources to setup with sticky-sessions yet, that's a later project. we need this running, and we need this running now. and we will loadbalance with DNS for a starter)

But then… If I want to take one server down, say, for maintenance, or a server crashes, or whatever reason. I don't want the users to just loose their sessions and have to start from the beginning… That's why we need some kind of replication, which Memcached does not support.

Then I found http://repcached.lab.klab.org/ — which has multi-master replication of memcached, which is great, and is what I want. But does it work with >2 machines? Say 3, 5, 10? For future scaling.

I also looked into redishttp://redis.io/ — which also seems great, but is a bit more "shaky" with the php-session-handler support, and no multi-master-replication.

The thing is that I like to use memcached, but I want to be able to power down one of two boxes without loosing half of the sessions. Any suggestions?

Best Answer

You might want to have a look at couchdb which implements replicated key store with a memcache API. It also handles overflow of the memory storage more gracefully than most memcache implementations (a likely outcome during failover). I must admit that I'm not familiar with the details of how it implements replication.

All the implementations of 'sticky' sessions I've seen bind the request to an explicit device - which does not make for good failover - and with PHP the session affinity is only relevant to the storage substrate (unlike in Java where it usually needs to be at the logic tier). So using sticky sessions at the HTTP tier is irrelevant.

Certainly using asynchronous MySQL replication in the substrate is not trivial due to replication lag and single thread write operations - I use a connection broker in PHP (which implements preference and blocks during failover) to address this. Although MySQL is not the most efficient solution for session handling, if your applications are already relying on a high-availability relational database, then it makes a lot of sense to use it for session storage. There are multi-master replication implementations for MySQL - e.g. Percona.

MongoDB also uses asynch replication, but without the single thread dependency of MySQL.

You're going to have to spend some time thinking about how you fence nodes. Virtual address takeover (if implemented correctly) should make the operation transparent, but IME it can be tricky to get right and it needs to takeover the arp address as well as the IP address to avoid big pauses during failover.

Say 3, 5, 10? For future scaling

If you're planning to scale to this extent, then you should probably be thinking about multiple data centres - which implies a synchronization method which can cope with low bandwidth / higher latency i.e. not a shared filesystem.