为什么不能用 memcached 存储 Sesion

为什么不能用 memcached 存储 Sesion
Memcached 创建者 Dormando 很早就写过两篇文章[1][2],告诫开发人员不要用
memcached 存储 Sesion。他在第一篇文章中给出的理由大致是说,如果用
memcached 存储 Sesion,那么当 memcached 集群发生故障(比如内存溢出)或
者维护(比如升级、增加或减少服务器)时,用户会无法登录,或者被踢掉线。
而在第二篇文章中,他则指出,memcached 的回收机制可能会导致用户无缘无故
地掉线。
Titas Norkūnas 是 DevOps 咨询服务提供商 Bear Mountain 的联合创始人。由于看
到 Ruby/Rails 社区忽略了 Dormando 那两篇文章所指出的问题,所以他近日撰文
对此进行了进一步的阐述。他认为问题的根本在于,memcached 是一个设计用于
缓存数据而不是存储数据的系统,因此不应该用于存储 Sesion。
对于 Dormando 的那两篇文章,他认为第一篇文章给出的原因很容易理解,而人
们经常会对第二篇文章给出的原因认识不足。因此他对这个原因进行了详细地阐
述:
Memcached 使用“最近最少使用(LRU)”算法回收缓存。但 memcached 的 LRU
算法针对每个 slab 类执行,而不是针对整体。
这意味着,如果所有 Sesion 的大小大致相同,那么它们会分成两三个 slab 类。
所有其它大小大致相同的数据也会放入同一些 slab,与 Sesion 争用存储空间。
一旦 slab 满了,即使更大的 slab 中还有空间,数据也会被回收,而不是放入更
大的 slab 中……在特定的 slab 中,Sesion 最老的用户将会掉线。用户将会开始
随机掉线,而最糟糕的是,你很可能甚至都不会注意到它,直至用户开始抱怨……
另外,Norkūnas 提到,如果 Sesion 中增加了新数据,那么 Sesion 变大也可能
会导致掉线问题出现。
有人提出将 Sesion 和其它数据分别使用单独的 memcached 缓存。不过,由于
memcached 的 LRU 算法是局部的,那种方式不仅导致内存使用率不高,而且也
无法消除用户因为 Sesion 回收而出现随机掉线的风险。
如果读者非常希望借助 memcached 提高 Sesion 读取速度,那么可以借鉴
Norkūnas 提出的 memcached+RDBMS(在有些情况下,NoSQL 也可以)的模式:
 当用户登录时,将 Sesion “set”到 memcached,并写入数据库;
 在 Sesion 中增加一个字段,标识 Sesion 最后写入数据库的时间;
 每个页面加载的时候,优先从 memcached 读取 Sesion,其次从数据库读
取;
 每加载 N 页或者 Y 分钟后,再次将 Sesion 写入数据库;
 从数据库中获取过期 Sesion,优先从 memcached 中获取最新数据。
关于 memcached 的更多信息,可以查看这里。

猜你喜欢

转载自flyvszhb.iteye.com/blog/2203698