Potential issue when using memcache session save handler in PHP
I have two load balanced web servers, and I'm using the memcache session save handler with the save path pointing to two memcache servers. It's configured with session redundancy set to two (the number of memcache servers). So PHP is writing session data to both memcache servers, and when I take one of the servers down, everything seems to work fine since the session data has been written to both memcache servers.
The problem seems to happen when I use the app for a while with only the one memcache server up, and then开发者_开发问答 bring the other one back up. My theory is that the memcache server comes back up, and PHP then starts asking it for session data which isn't there since it was written to the other server while this one was down. Is there any merit to this theory? Should PHP be asking both servers for the session data and maybe there's some other problem?
EDIT: I'm using version 2.2.6 of the PECL memcache package.
It's got a lot to do with how memcache is actually distributed. Essentially, you initialise a client with a list of one or more servers that it can use. When you do a write, data is only sent to one server, not all.
The client is responsible for hashing the cache key to determine which server it should connect to, both for reads and writes - the same principle as a hash table deciding which bucket a given key likely resides in. Some memcache clients can be given weight information, etc. to make their decisioning better.
In your case, you appear to be initialising the client with two servers, and then dropping one out of service. If you're reconfiguring (e.g. by commenting out) the list of servers, then you're effectively changing that hashing strategy on the fly, and it's inconsistent with the one used to determine where data should be stored. When you bring the other server back up, the client re-incorporates it into the hash calculation, and then that becomes inconsistent with how the data was stored.
The typical workaround for this I've seen is to try and avoid changing the number (or order) of memcached instances actually running, usually by preparing a number of spares. These can be lower-resourced nodes running ready on the same box as your other instances, if you like - and they don't even need to be hot spare, as long as you bring them up when you change the memcache configuration.
Obviously, if you're using memcache to store "important" data, like session information, that isn't persisted elsewhere, then you care more about maintaining this sort of integrity than if you were really just using it as a throwaway cache that, at worst, would affect your performance for a while. It's a compromise, really.
Worth a read:
- http://code.google.com/p/memcached/wiki/FAQ#How_does_memcached_work?
- http://www.mikeperham.com/2009/01/14/consistent-hashing-in-memcache-client/
According to the Memcache PECL page the session_redundancy ini option has only been available since version 3.0.0
http://pecl.php.net/package/memcache/3.0.0
Try to download the latest version and install (pecl install /path/to/tgz) and see if you still get the error.
Try using a consistent hashing strategy by using the following php.ini setting:
memcache.hash_strategy = consistent
This allow servers to be added or removed from the pool without causing the keys to be remapped to other servers.
http://blog.fedecarg.com/2008/12/24/memcached-consistent-hashing-mechanism/
精彩评论