为什么不能用memcached存储Session?

为什么不能用memcached存储Session?

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中获取最新数据。

原文发布时间:2015-01-29

本文来自云栖合作伙伴“linux中国”

时间: 2024-09-28 06:10:17

为什么不能用memcached存储Session?的相关文章

基于php使用memcache存储session的详解

web服务器的php session都给memcached ,这样你不管分发器把 ip连接分给哪个web服务器都不会有问题了,配置方法很简单,就在php的配置文件内 增加一条语句就可以了,不过前提你需要装好memcache模块 1.设置session用memcache来存储方法I: 在 php.ini 中全局设置 session.save_handler = memcache session.save_path = "tcp://127.0.0.1:11211" 方法II: 某个目录下

基于php使用memcache存储session的详解_php技巧

web服务器的php session都给memcached ,这样你不管分发器把 ip连接分给哪个web服务器都不会有问题了,配置方法很简单,就在php的配置文件内增加一条语句就可以了,不过前提你需要装好memcache模块 1.设置session用memcache来存储方法I: 在 php.ini 中全局设置session.save_handler = memcachesession.save_path = "tcp://127.0.0.1:11211"方法II: 某个目录下的 .h

php使用memcache存储session时,session的生命周期

问题描述 php使用memcache存储session时,session的生命周期 默认 session.save_handle=files session.gc_probability = 1 session.gc_divisor = 100 session.gc_maxlifetime = 1440 此时,session的生命周期为1440,超过这个时间session有1/100的几率被回收. 如果使用memcache存储session,memcache中的session的生命周期也是144

Ubuntu server 11.04安装memcache及php使用memcache来存储session的方法_php技巧

本文实例讲述了Ubuntu server 11.04安装memcache及php使用memcache来存储session的方法.分享给大家供大家参考,具体如下: 1.首先安装memcache服务端: sudo apt-get install memcached 安装完成后系统 自动启动了 memcached服务占用11211端口 如需重新配置11211端口的服务 需要关闭已开启的memcached服务 手动启动: memcached -d -m 128 -p 11211 -u memcache

Weblogic92中使用JDBC store存储session时问题分析

Weblogic92中,不少系统为了降低系统的内存开销,抑或防止session丢失,管理人员会是用JDBC store来存放session信息.不过在使用这种配置的时候,不少客户反映会碰到约束冲突的异常信息,如下, <Jan 23, 2009 10:07:33 AM CST> <Error> <HTTP Session> <BEA-100087> <The jdbc session data for session id: DcwFJ5mH1HbFrV

PHP中使用memcache存储session的三种配置方法

 下面简单说下PHP项目分布式部署中,SESSION的同步方案中的一种,使用Memcache来存储SESSION.并总结了三种配置方式,需要的朋友可以参考下   1.直接修改php.ini配置文件  代码如下: session.save_handler = memcache //设置session的储存方式为memcache  memcache.hash_strategy = "consistent"//设置memcache的hash算法  session.save_path = &q

javascript-jsp 在JavaScript存储session和取值

问题描述 jsp 在JavaScript存储session和取值 alert(rec.platformName); 能得到值 '<%=session.setAttribute("platformName",rec.platformName)%>';这个就不能保存了 解决方案 JSP获得JS数据一定要提交以后才能获得,JS获得JSP数据可以直接获得 .拼个form表单提交,然后获取值就行 解决方案二: onSelect: function(rec){ 在这里得到platfor

spring mvc-新手学SpringMvc存储session的问题

问题描述 新手学SpringMvc存储session的问题 @Controller@SessionAttributes(""user"")public class UserController { @Resource private UserService userService;@RequestMapping(""/login"") public ModelAndView getLogin( User userModelMa

Tomcat利用Redis存储Session

如果英文不错的看,建议直接看官网吧,官网写的挺清楚.下面的内容是转载的一篇文章,自己补充了一些,供大家参考,也欢迎大家一起讨论 截止到2015-05-12前是不支持Tomcat8的,详情见官网:https://github.com/jcoleman/tomcat-redis-session-manager 前提:你已经部署了Redis,尚未学会的,可以移步这里:http://blog.csdn.net/caiwenfeng_for_23/article/details/45511007 其实很简