在容错Memcached池中的PHP会话存储

我最近有机会将Web应用程序从使用Nginx代理“loadbalancer”转移到F5负载均衡器。 不幸的是,在迁移过程中,很明显memcached会话存储需要从Nginx代理服务器转移到“某处”。 我的想法是,我应该把memcached放在所有3台Web服务器(位于池中的F5后面的服务器)上,并使用php-memcachephp-memcached来保存会话。 这是麻烦:

我已经尝试了php-memcachephp-memcached ,如果其中一台服务器出现故障,则无法正常运行。 我最近的尝试是使用这种configuration:

memcached版本2.2.0与configuration设置:

 session.save_handler = memcached
 session.save_path =“172.29.104.13:11211,172.29.104.14:11211”

除了extension=memcached.so以外,我在memcached.ini没有任何特别之处。

通过在服务器1和2上的这个configuration(我暂时移除了3个testing),我将JMeter指向F5 VIP并启动stream量。 我可以在两个系统上看到memcached.log (守护进程),尽pipe没有花时间解密,开始运行。

然后,如果我停止一个memcached守护进程,stream量开始失败,我的回报是

session_start(): Write of lock failed

剩下的memcached

在一天结束的时候,我的目标很简单 – 我需要能够:a)不在单个服务器上运行memcached (单点故障),并且集群需要对池成员的故障具有恢复能力。

我也试过php-memcache但是也失败了。 对于php-memcache ,configuration如下所示:

memcache版本3.0.8(testing版)与configuration设置:

 
 session.save_handler = memcache
 session.save_path =“tcp://172.29.104.13:11211,tcp://172.29.104.14:11211”

memcache.ini

延长= memcache.so
 [内存caching]
 memcache.dbpath = “的/ var / lib中/内存caching”
 memcache.maxreclevel = 0
 memcache.maxfiles = 0
 memcache.archivememlim = 0
 memcache.maxfilesize = 0
 memcache.maxratio = 0
 memcache.hash_strategy =一致
 memcache.allow_failover = 1
 memcache.session_redundancy = 2

这里的错误只是无效的会话令牌(意味着剩下的服务器没有实际存储的会话令牌,意味着保存会话的复制不是活动的)。

我没有把会话持久性放回到F5上,尽pipe我可以这么做,而试图连接失去的成员的客户端将不得不重新进行身份validation。

使客户端在Cookie中存储会话状态要简单得多。 这意味着在所有服务器端没有会话存储,只有几微秒的CPU使用率来解密和validationcookie。 由于CPU是数据中心中最丰富的资源,因此该scheme比从memcached或任何其他服务器会话存储查找性能要好得多。

一个实现请参阅https://github.com/ascorbic/php-stateless-cookies ,还有其他许多人在踢。 请注意会话数据应该被encryption,但必须通过HMAC或AEAD密码进行validation。 不要自己写这个代码,除非你是密码学家; 使用一个经过严格审查的cryoto图书馆。

Facebook使用这种技术,因此任何服务器都可以回答任何用户请求,即使用户会话是在另一个数据中心启动的。