[转]为何不能用memcached存储Session

如下内容转自:http://www.infoq.com/cn/news/2015/01/memcached-store-sessionhtml

-------------------------分割线-----------------------------------------------算法

Memcached建立者Dormando很早就写过两篇文章[1][2],告诫开发人员不要用memcached存储Session。他在第一篇文章中给出的理由大体是说,若是用memcached存储Session,那么当memcached集群发生故障(好比内存溢出)或者维护(好比升级、增长或减小服务器)时,用户会没法登陆,或者被踢掉线。而在第二篇文章中,他则指出,memcached的回收机制可能会致使用户平白无故地掉线。

Titas Norkūnas是DevOps咨询服务提供商Bear Mountain的联合创始人。因为看到Ruby/Rails社区忽略了Dormando那两篇文章所指出的问题,因此他近日撰文对此进行了进一步的阐述。他认为问题的根本在于,memcached是一个设计用于缓存数据而不是存储数据的系统,所以不该该用于存储Session。

对于Dormando的那两篇文章,他认为第一篇文章给出的缘由很容易理解,而人们常常会对第二篇文章给出的缘由认识不足。所以他对这个缘由进行了详细地阐述:

Memcached使用“最近最少使用(LRU)”算法回收缓存。但memcached的LRU算法针对每一个slab类执行,而不是针对总体。

这意味着,若是全部Session的大小大体相同,那么它们会分红两三个slab类。全部其它大小大体相同的数据也会放入同一些slab,与Session争用存储空间。一旦slab满了,即便更大的slab中还有空间,数据也会被回收,而不是放入更大的slab中……在特定的slab中,Session最老的用户将会掉线。用户将会开始随机掉线,而最糟糕的是,你极可能甚至都不会注意到它,直至用户开始抱怨……

另外,Norkūnas提到,若是Session中增长了新数据,那么Session变大也可能会致使掉线问题出现。

有人提出将Session和其它数据分别使用单独的memcached缓存。不过,因为memcached的LRU算法是局部的,那种方式不只致使内存使用率不高,并且也没法消除用户由于Session回收而出现随机掉线的风险。

若是读者很是但愿借助memcached提升Session读取速度,那么能够借鉴Norkūnas提出的memcached+RDBMS(在有些状况下,NoSQL也能够)的模式:

当用户登陆时,将Session “set”到memcached,并写入数据库;
在Session中增长一个字段,标识Session最后写入数据库的时间;
每一个页面加载的时候,优先从memcached读取Session,其次从数据库读取;
每加载N页或者Y分钟后,再次将Session写入数据库;
从数据库中获取过时Session,优先从memcached中获取最新数据。
关于memcached的更多信息,能够查看这里[3]。

感谢郭蕾对本文的审校。

[1]:http://www.dormando.me/articles/memcached_sessions/数据库

[2]:http://dormando.livejournal.com/495593.html缓存

[3]:http://work.tinou.com/2011/04/memcached-for-dummies.html服务器

-----------------------------分割线---------------------session

PS:LRU算法和Memcache有空在整理下memcached

相关文章
相关标签/搜索