如果不能正常显示,请查看原文 , 或返回

分布式的session共享

session的复制与共享

在web应用中,为了应对大规模访问,必须实现应用的集群部署.要实现集群部署主要需要实现session共享机制,使得多台应用服务器之间会话统一, tomcat等多数主流web服务器都采用了session复制以及实现session的共享. 但问题还是很明显的:

在节点持续增多的情况下,session复制带来的性能损失会快速增加.特别是当session中保存了较大的对象,而且对象变化较快时,性能下降更加显著.这种特性使得web应用的水平扩展受到了限制.

session共享的另一种思路就是把session集中起来管理,首先想到的是采用数据库来集中存储session,但数据库是文件存储相对内存慢了一个数量级,同时这势必加大数据库系统的负担.所以需要一种既速度快又能远程集中存储的服务:memcached

memcache的seesion共享

使用memcached来存储session有两种方案:

  1. 直接通过tomcat6的扩展机制实现.

    Reference: http://www.javaeye.com/topic/81641

  2. 通过自己编写filter实现.

    考虑到系统的扩展,我们采用这种方案.这样可以使session共享机制和中间件脱钩.

    Reference: http://www.javaeye.com/topic/82565

    主要思路:

    1)继承重构HttpServletRequestWrapper,HttpSessionWrapper类,覆盖原来和session存取相关的方法呢,都通过SessionService类来实现.

    2)使用filter拦截cookie中的sessionId,通过sessionId构造新的HttpServletRequestWrapper对象,传给后面的应用.

    3)SessionService连接memcached服务,以sessionId作为key,存取的对象是一个map.map的内容即为session的内容.

使用过程注意几个问题和改进思路:

  1. memcache的内存应该足够大,这样不会出现内存不足时用户session从Cache中被清除的问题(可以关闭memcached的对象退出机制)。

  2. 如果session的读取比写入要多很多,可以在memcache前再加一个Oscache等本地缓存,减少对memcache的读操作,从而减小网络开销,提高性能。

  3. 如果用户非常多,可以使用memcached组,通过set方法中带hashCode,插入到某个memcached服务器

Memcached 管理 session

使用memcached-session-manager管理session

Reference: http://www.iteye.com/topic/1125301

对于session的清除有几种方案:

(1)可以在凌晨人最少的时候,对memcached做一次清空。

(2)保存在缓存中的对象设置一个失效时间,通过过滤器获取sessionId的值,定期刷新memcached中的对象.长时间没有被刷新的对象自动被清除.(相对复杂,消耗资源)

Memcache高可用共享session的一个方案

Memcache高可用共享session,容纳100万人同时在线 : http://blog.csdn.net/kongdeqian1988/article/details/38434457

  1. 采用repcached方案Memcache挂掉。

  2. memcache协议内容:

    在 Memcached中可以保存的item数据量是没有限制的,只要内存足够 。  
    Memcached以单进程多线程方式运行,32位中最大使用内存为2G,这个由于内核限制,在64位中取决于物理内存限制,  
    在32位中要使用更多内存,可以分多个端口开启多个Memcached进程   
    最大30天的数据过期时间,设置为永久的也会在这个时间过期,常量REALTIME_MAXDELTA  60*60*24*30控制   
    最大键长为250字节,大于该长度无法存储,常量KEY_MAX_LENGTH 250控制   
    单个item最大数据是1MB,超过1MB数据不予存储返回false,常量POWER_BLOCK 1048576进行控制,   
    它是默认的slab大小 最大同时连接数是200,通过 conn_init()中的freetotal进行控制,最大软连接数是1024,  
    通过 settings.maxconns=1024 进行控制 ,需要说明的一点是memcache处理请求是以队列形式处理的  
    跟空间占用相关的参数:settings.factor=1.25, settings.chunk_size=48, 影响slab的数据占用和步长比  
    memcached是一种无阻塞的socket通信方式服务,基于libevent库,由于无阻塞通信,对内存读写速度非常之快。  
    memcached分服务器端和客户端,可以配置多个服务器端和客户端,应用于分布式的服务非常广泛。  
    memcached作为小规模的数据分布式平台是十分有效果的。  
    memcached是键值一一对应,key默认最大不能超过128个字 节,value默认大小是1M,也就是一个slabs,如果要存2M的值(连续的),不能用两个slabs,因为两个slabs不是连续的,无法在内存中 存储,故需要修改slabs的大小,多个key和value进行存储时,即使这个slabs没有利用完,那么也不会存放别的数据。  
    memcache假定设置64m内存占用,当内存已满时采用LRU算法(最近最少使用)进行剔除旧数据然后存储新数据  
    
  3. memcache内存分配如何支撑高并发用户:

    memcache 如果分配2G内存,以每个用户2K数据计算,512*2048≈100万人在线,由于memcache自身也点用一定内存,

    实际2G内存可能只有80%利用1.6G,如果分配2G内存,基本可以保持100万人在线,session存在memcache的另一个好处是

    不用担心过期session过多的删除问题,memcache自动过期,自动LRU剔除

    memcache默认连接1秒超时,设置过大失去缓存意义,数据最大1M也是基于此点考虑,当内存使用超过1G后数据太大导致超时无法命中继而导致缓存刺穿压到后方的DB memcache只能存储字符串与数组,字符串直接存储,数组自动序列化后存储文件,图片,视频需要打成二进制后再存储, 资源连接不能保存

其他概念

分布式缓存的设计

:在多台Node的环境下,产生的缓存以及缓存的变化,如何处理?

To be continued…

  1. 数据库的sharing, 当数据量越来越大,数据需要迁移时,对不同的分库,分表(区),业务数据处理层如何能够适应底层的变化?

使用DDL:Sharding扩容方案-全局增量+局部hash散列

一个大型的互联网 应用必然会经过一个从单一DB server,到Master/salve,再到垂直分区(分 库),然后再到水平分区(分表,sharding)的过程(随着用户量的不断增加,你会发现系统中的某些表会变的异常庞大,比如好友关系表,店铺的参数配置表等,这个时候 无论是写入还是读取这些表的数据,对数据库来说都是一个很耗费精力的事情),而在这个过程中,Master/salve 以 及垂直分区相对比较容易,对应用的影响也不是很大,但是分表会引起一些棘手的问题,比如不能跨越多个分区join查 询数据,如何平衡各个shards的 负载等等,这个时候就需要一个通用的DAL框架来屏蔽底层数据存储对应用逻辑的影响,使得底层数据的访问对应用透明化。

拿淘宝目前的情况来说,淘宝目前也正在从昂贵的高端存储(小型机+ORACLE)切换到MYSQL,切 换到MYSQL以 后,势必会遇到垂直分区(分库)以及水平分区(Sharding)的问题,因此目前淘宝根据自 己的业务特点也开发了自己的TDDL(Taobao Distributed Data Layer)框架,此框架主要解决了分库分表对应用的透明化以及异构数据库之间的数据复制。

淘宝网采用什么技术架构来实现网站高负载的呢?淘宝的整体架构使用了如下措施来应对:一应用无状态(淘宝session框架);二有效使用缓存(Tair);三应用拆分(HSF);四数据库拆分(TDDL);五异步通信(Notify);六非结构化数据存储(TFS,NOSQL);七监控、预警系统;八配置统一管理。

http://code.taobao.org/p/tddl-dynamic-datasource/wiki/index/

铁道部网站为何登录会挂,进入之后就不会。

登录的时候,因为没有足够的服务相应用户的查询请求,负载均衡不够,服务器非常繁忙,导致无法登录。登录进入的人少了,那登录进去的用户基本上在网站的承载范围内,所以登录之后只会慢,不会挂掉。

使用CDN, 足够的服务器集群,负载均衡,缓存存取用户信息,通过测试让系统容量能够达到2kw级别,即可让更多的用户登录进系统。真正的问题不在登录,而在登录之后的对票的查询与巧夺。查询可以通过单独的查询集群服务来解决。最困难的是最有限的资源的争夺(1.火车票的状态是实时计算,实时更新的;2.火车票资源稀缺,需要同线下数以万计的购票点、电话订票等进行互斥。每张火车票都是独一无二的,网络售票只是数以万计的购票终端的一个终端而已,需要跟其他售票系统保持数据一致性)。

solution 1: 设定容忍度: 绝对不能两个人订到同一张票,而看到有票,而点击了下订单又说没票了这种失误是可以容忍的。

solution 2: 排队,异步告知前面多少人,轮到之后,规定时间下单(查询需要的票,下单到的票锁住,timeout则踢出)

solution3: 100w有效点击的用户,随机摇出能否负载的用户数(10w)

点击订票之后,进入前置分析机,分析机负责计算背后的机器能负载多少用户下订单。比如目前有1百万人同时点击了订票,而背后只能负载10万人,那么出现一个随机摇号程序,摇出10万人,其他人返回 “系统繁忙,稍后重试”的提示。这10万人被负载在10台机器上,可以进行查询,当点击指定车票(标记为ClickSelectedTicket)后,根据车票被分散到不同的机器上(其实是MapReduce的思想)。比如有1万人被定位到要订票T1,系统扔出900张T1票,留100张容错(随着系统逐步稳定,可减少容错票数),然后大家抢锁,采用乐观离线锁。在最终提交订单时检测。

返回