标签:
使用Tair(key-value)存储session(其他:使用memcached存储session)
高并发下分布式问题
透明处理存储介质的故障转移
动态增删节点,减小“缓存颠簸”问题
保证数据在各个节点的分布均衡
Session 序列化和反序列化
BASE 策略
Eric A. Brewer 在 1988 年提出的 BASE 策略,即 Basically Available、Soft state、和Eventually consistent。
互联网大多数应用更强调可用性,即牺牲高一致性,获得可用性或可靠性。
Hash取模算法
基于 memcache 的 Hash取模算法(hash() mod n,hash() 取用户ID,n为节点数) 实现的分布式 Session 方案,就属于基本可用:
第一,如果节点发生故障,该节点上的所有用户 Session 丢失,系统无法自恢复。
第二,如果系统压力突然增大,需要临时增加机器节点。按照 Hash取模的算法,在增加机器节点的这一时刻,大量缓存无法命中(其实还都存在之前的节点上),导致大范围的缓存穿透,压力会直接打到数据库上。
第三,根据 LRU 缓存失效算法,memcache 里存储的 key/value 有可能被踢出,用户 Session 容易丢失。
一致性哈希算法
【基于一致性哈希算法的 memcache 解决方案 】
1)一致性哈希帮我们解决的是,当机器节点减少时,缓存数据能进行最少重建。
2)还能解决 Session 数据的分布均衡问题。
3)当机器节点宕机,这部分数据必然丢失。由于节点数目变化,有可能对部分没有丢失的数据也要重建。
但上面的方案都解决不了“一个节点失败后,它所存储的 Session 如何由其他节点获取以便接替失效节点,实现集群的容错(Failover)”。
ZooKeeper 集群
【基于 ZooKeeper 集群的分布式 Session 方案】【http://my.oschina.net/mn1127/blog/210282】
要解决基于 memcache 方案的数据丢失问题,可以引入持久化存储介质 ZooKeeper(下面简称 ZK)。
依托于 ZK 的一致性复制(在多个副本间保证数据的强一致性)和容错能力,结合上面的 MSM 思想,
由 ZK 负责 session 数据的存储,而我们自己实现的 session manager 将负责 session 生命周期的管理。
http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard36.png
微软系的解决方法
ASP.NET 有自己的分布式 Session 解决方案,Session State Server ,即 web.config 里指定 sessionState 的 mode 为“StateServer”即可。
郑昀既可以在 web.config 里指定一个 State Server :
http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard37.png
也可以实现 System.Web.IPartitionResolver 的接口,自行决定如何构造 Session State Server 连接字符串,从而支持一组 State Servers。
郑昀也可以用 sessionState 的 partitionResolverType 属性设定即可:
http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard38.png
微软的这个解决方案缺点是,Session State 中的序列化和反序列化对象将成为主要性能消耗之一,最好使用基本类型来存储所有的 Session State 数据。
把应用做成无状态的,会比较容易实现水平伸缩。
stateless是更好的,主要有3个原因:
1、负载均衡不需要做session绑定,也就可以用更简单的算法,比如随机、取模等,把请求分配到任意server上,因此相对于session绑定的做法,性能会比较好。
2、也是性能的问题,在7层网络模型中,session位于第7层,负载均衡如果是基于session的算法来决定要怎么分发请求,性能的损耗也会比较大。
3、如果某一台server down掉了,后续的请求就没法继续往这台server发了,影响可用性。
如果将请求所需的信息,都放在cookie里,确实就不需要session框架了,而且也比较容易实现stateless。但是cookie也有自己的问题,cookie的大小是有限制的,还会增大网络流量(对于淘宝这种规模的应用,绝对不是一个小数),并且数据放在客户端,多少有点不安全。
所以session还是要用的,但是如果session都放在app server里,stateless就不容易实现了,而且为了HA,还涉及到session迁移的问题,会比较复杂。所以淘宝自己搞了一个session框架出来
具体的实现就不清楚,不过知道了这个思路,也不是很困难。我猜应该类似于把session集中放在session server里,其他的app server都来共享就可以了。然后将session server做成集群,避免单点故障。同时session迁移的事情,也就转化成了集群的迁移。
假如在session中保存了大量与客户端的状态信息,保存状态信息的server宕机时通常通过集群解决,不仅有负载均衡,更重要的是要有失效恢复failover。
tomcat用集群节点广播复制,jboss用配对复制等session状态复制策略,但严重影响系统的伸缩性,不能通过增加更多的机器达到良好的水平伸缩因为集群节点间session通信随着节点的增多而开销增大,因此要想做到应用本身的伸缩性,要保证应用无状态,这样集群中的各个节点来说都是相同的,使系统更好的水平伸缩
淘宝的session框架用clientcookie实现,将状态保存到cookie里,使应用节点本身不要保存状态信息,这样在系统用户变多的时候,就可以通过增加更多的应用节点来达到水平扩展的目的。但有限制,比如每个cookie一般不能超过4K的大小,很多浏览器都限制一个站点最多保存20个cookie
淘宝cookie框架是“多值cookie”,一个组合键对应多个cookie的值,可以防止cookie数量超过20,还节省了cookie存储有效信息的空间
除了淘宝目前的session框架的实现方式以外,其实集中式session管理来完成,说具体点就是多个无状态的应用节点连接一个session 服务器,session服务器将session保存到缓存中,session服务器后端再配有底层持久性数据源,比如数据库,文件系统等等。
淘宝在11年左右开始拆分应用,走“服务化”方向之后,应用拆分了很多个独立的子应用(大约有1000个左右)
这么多的应用要在一起完成业务,势必涉及到集成的问题。但是淘宝没有使用ESB,而是用了自研的服务框架和消息中间件
这主要是因为ESB更擅长处理异构系统的集成,而淘宝这将近1000个应用,基本都是JAVA应用,所以ESB的这个优势不明显;另外,增加机器水平伸缩,是淘宝的杀手锏,如果采用ESB架构的话,那在水平伸缩的时候,就连ESB那层也要一起伸缩,比较麻烦
淘宝网架构分享总结:http://kyfxbl.iteye.com/blog/1898209
标签:
原文地址:http://www.cnblogs.com/lsx1993/p/4638704.html