分布式系统开发常见问题-1. session的复制与共享 2. 分布式缓存的设计

1. session的复制与共享

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

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

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

使用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服务器

(3)使用memcached-session-manager管理session

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

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

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

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

2. 分布式缓存的设计:在多台Node的环境下,产生的缓存以及缓存的变化,如何处理?

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

 

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

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

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

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

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

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

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

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

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

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

转载:”当前 12306 系统一个很受人诟病的实现就是无法登录。用户打开登录页,输入了用户名密码,还耐心的填好了验证码,点击提交,再耐心的等了 30 秒,结果,弹出一个无比丑陋的对话框,说“当前访问用户过多,请稍后尝试”。让用户登录进来,给他们能买到票的希望,是减少投诉的一个很重要的方面。这个其实一点也不难:将用户信息都加载到 Redis 内存,简单点,key 就是 email,value 就是密码加密串,用 cookie 而不是 session 进行身份验证,用 ajax 而不是刷新页面的方式提交数据和返回应答,这么一来,即使 2 kw 用户同时都登录进来,也只需要三五台 tomcat ,20分钟就搞定了。“

优化方式:http://blog.csdn.net/fyxxq/article/details/8850531     http://blog.csdn.net/li0531/article/details/7991176

session与缓存的更多相关文章

  1. windows使用nginx+memcached实现负载均衡和session或者缓存共享

    windows使用nginx+memcached实现负载均衡和session或者缓存共享 两台server server1:115.29.186.215 windows2008 64位操作系统 ser ...

  2. 《前端之路》之 Cookie && localStorage && Session Storage 缓存相关

    08: Cookie && localStorage && Session Storage 缓存相关 客户端.前端 存储 一. 起 因 首先解释下为什么想来写这个关于前 ...

  3. hibernate Session一级缓存 应该注意的地方

    Session缓存 Hibernate的一级缓存是由Session提供的,因此它存在于Session的整个生命周期中,当程序调用save()/update()/saveOrupdate()/get() ...

  4. asp.net core webapi Session 内存缓存

    Startup.cs文件中的ConfigureServices方法配置: #region Session内存缓存 services.Configure<CookiePolicyOptions&g ...

  5. Django实现表单验证、CSRF、cookie和session、缓存、数据库多表操作(双下划綫)

    通常验证用户输入是否合法的话,是前端js和后端共同验证的,这是因为前端js是可以被禁用的,假如被禁用了,那就没法用js实现验证合法与否了,也就是即使用户输入的不合法,但是也没提示,用户也不知道怎么输入 ...

  6. Hibernate的session一级缓存

    一级缓存是Session周期的,当session创建的时候就有,当session结束的时候,缓存被清空 当缓存存在的时候,每次查询的数据,都会放在缓存中,如果再次查询相同的数据,则不会再次查询数据库, ...

  7. 使用cachemanager做缓存(Session的缓存)

    1.我在这里直接用 cachemanager.redis 往redis里面存储缓存数据2.步骤 1)下载CacheManager.Redis(包含了CacheManager.Core) 下载Stack ...

  8. Hibernate,Session清理缓存时间点

    当应用程序调用org.hibernate.Transaction的commit()的时候,commit()方法先清理缓存,然后再向数据库提交事务. 当应用程序显示调用Session.flush()方法 ...

  9. HttpServletRequestWrapper使用技巧(自定义session和缓存InputStream)

    一.前言 javax.servlet.http.HttpServletRequestWrapper 是一个开发者可以继承的类,我们可以重写相应的方法来实现session的自定义以及缓存InputStr ...

随机推荐

  1. requirejs之demo (转)

    具体的理论就不讲了,可以参考 http://www.ruanyifeng.com/blog/2012/10/javascript_module.html http://www.ruanyifeng.c ...

  2. 删除github.com上repository(仓库)的方法

    第一步:打开http://github.com,看到右侧仓库列表.第二步:假设要删除“HiTop”这个参考,点击对应仓库进入详细页面之后,在右侧会看到“Settings”入口. 第三步:进入设置页面之 ...

  3. mysql初识之数据文件及其他文件

    在mysql中数据文件存放于在my.cnf中datadir指定的路径,使用的表引擎不同产生的文件格式.表文件个数也会有所差异.mysql的表引擎有多种,表的扩展名也不一样,如innodb用“ .ibd ...

  4. windows7操作系统64位安装ArcSDE10.1和Oracle11g

    安装环境如下: Oracle11g R2 64位服务端Oracle11g R2 32位客户端(管理员,第二项)ArcSDE10.1 for Oracle11g SDE数据库可由其它机器安装Arcata ...

  5. android性能小贴士 翻译

    转自http://developer.android.com/training/articles/perf-tips.html 性能小贴士: 这篇文档主要一些微优化可以提升应用程序性能,但是这些改变不 ...

  6. C# 对Excel 单元格格式, 及行高、 列宽、 单元格边框线、 冻结设置

    一.对行高,列宽.单元格边框等的设置 这篇简短的文字对单元格的操作总结的比较全面,特此转载过来. private _Workbook _workBook = null; private Workshe ...

  7. Java魔法类:sun.misc.Unsafe

    Unsafe类在jdk 源码的多个类中用到,这个类的提供了一些绕开JVM的更底层功能,基于它的实现可以提高效率.但是,它是一把双刃剑:正如它的名字所预示的那样,它是Unsafe的,它所分配的内存需要手 ...

  8. OSX学习01之更新头像

    前不久在官网上守株待兔,买了一个官翻版865,其实最想买294的,可是米不足啊——所以,在同时下了865和293的订单,并纠结了一天后,确定了865,剩余的钱够一个Mac mini了,如果不买也可以日 ...

  9. 腾讯2015校招一面、二面、HR面

    其实我目前的理想公司就是腾讯. 内推第三面跪了··· 现在校招. 已面完一面.二面.HR面··· 一面主要问我项目和Linux.网络··· 二面主要问我游戏服务器··· 然后是HR面··· 技术面我都 ...

  10. 2014搜狗前端面经【A事业部】

    刚刚面完搜狗,有种莫名其妙的感觉,哪里莫名其妙呢?听我慢慢道来... 开始面试官就这简历,问了一些有的没的东西,都不深(好吧我承认之前的经历有点菜,没神马加分项啊). 后面开始技术面: 知识点1:JS ...