秒杀系统设计方案
一、秒杀系统架构设计关键点
1.两个问题,一个备选方案
(1)秒杀其实主要解决两个问题
一个是并发读,并发读的核心理念是尽量减少用户到服务端来“读”数据,或者读更少的数据。
一个是并发写,并发写我们在数据库层面独立出来一个库,做特殊的处理。
(2)还要针对秒杀系统做一些保护,针对意料之外的情况设计兜底案,以防止最坏的情况发生。
2.从架构师的角度来看,要想打造超大流量并发读写、高性能、高可用的系统,我们要遵循几个原则
(1)请求的数据尽量少
(2)请求数尽少
(3)并且不要有单点
3.技术角度上看“稳、准、快”
(1)高性能中高并发访问非常关键,处理方式有以下4点
设计数据的动静分离方案、
热点的发现与隔离、
请求的削峰与分层过滤、
服务端的极致优化、
(2)一致性中商品减库存的实现方式同样关键,主要有以下两种扣减方式
拍下减库存
付款减库存
(3)高可用还要设计一个备选来兜底
二、秒杀系统应该注意的5个原则(结合业务动态平衡)
1.数据要尽量少
(1)用户请求的数据能少就少
用户请求的数据包括,上传给系统的数据和系统返回的数据。用户请求的数据尽量少的原因是,网络上数据传输需要时间,不管是请求数据还是返回数据都需要服务器做处理,服务器在做网络通信都要做压缩和字符编码,这些都非常消耗CPU,所以要减少传输的数据量。
(2)系统依赖的数据能少就少
系统要完成某些业务需要读取和保存数据,一般需要和后台服务及数据库打交道。调用其他服务会涉及数据的系列化和反序列化,而这些也是CPU的一大杀手,同样也会增加延时。数据库本身也容易是一个瓶颈,所以和数据库打交道越少越好,数据越简单、越小则越好。
2.请求数要尽量少
(1)额外请求尽量减少
浏览器每发出一个请求都会有一些消耗,如三次握手,有的时候页面或者链接数限制,一些请求还需要串行加载等。域名不一样的话,还涉及这些域名的DNS解析,可能会耗时更久。
(2)合并CSS和JavaScript文件
在URL中用逗号隔开,在服务端仍然是单个文件各自存放,服务端自动解析这个URL,合并成一个文件一起返回。
3.路径要尽量短
(1)经过一个节点一般都会产生一个socket链接
缩短请求路径不仅可以增加可用性,还可以提升性能(序列化、反序列化),减少延时(网络传输耗时)。
(2)RPC调用换成JVM调用
RPC调用换成JVM调用酌情处理。
4.依赖要尽量少
(1)完成一次用户请求必须依赖的系统或者服务尽量减少
若依赖在紧急情况下可以去掉,比如:秒杀页面,这个页面必须强依赖商品信息、用户信息,还有其他优惠券、成交列表这些对秒杀不是非要不可的信息,在紧急情况下可以去掉。
(2)建立系统级别
我们可以给系统进行分级,比如:0 级系统、1 级系统、2 级系统、3 级系统,0 级系统如果是最重要的系统,那么 0 级系统强依赖的系统也同样是最重要的系统,以此类推。0 级系统要尽量减少对 1 级系统的强依赖,防止重要的系统被不重要的系统拖垮。
5.不要有单点
(1)设计系统最重要的就是消除单点
单点意味着没有备份,风险不可控
(2)避免单点的方案
避免服务和状态绑定,服务无状态化。比如:把机器和相关配置动态化,配置通过配置中心动态推送。
三、不同场景下的不同架构案例
1.比如从 1w/s 到了 10w/s 的量级
把秒杀系统独立开发,针对性的做优化。系统部署上做机器集群,秒杀流量不会影响正常商品购买。热点数据单独存放在一个独立的缓存系统,提高性能。增加秒杀答题,防止有秒杀器抢单。
2.100w/s的请求量级
对页面进行彻底动静分离,使秒杀时不需要刷新整个页面,只需要点击抢宝按钮,把刷新的数据降到最少。服务端对秒杀商品进行本地缓存,不需要调用依赖系统的后台服务获取数据,甚至不需要去公共缓存集群中查询数据,这样不仅可以减少系统调用,而且能够减少公共缓存集群的压力。增加系统限流保护,防止最坏情况发生。
四、动静分离可选方案
1.动态数据和静态数据的定义
动态数据跟访问者相关的个性化数据,静态数据包括存放在硬盘上的html页面,和与访问者无关的由业务处理数据
2.静态数据做缓存的要点
静态数据缓存到离用户最近的地方。可以存在(浏览器、CDN、服务器Cache),
静态化改造(直接缓存http链接,而不是仅仅缓存数据),
Web服务器直接缓存静态数据(nginx、apache)。
3.动静分离5个方面
URL唯一化(分区保存)
分离浏览者相关因素(是否登录、登录身份等,通过动态请求获取)
分离时间因素(服务器输出时间通过动态请求获取)
异步化地域因素(通过异步获取地域相关信息)
去掉Cookie,静态页面不含cookie(通过代码软件删除)
4.静态数据和动态数据组装
在代理服务器上做动态数据请求,并将动态数据插入到静态页面中
浏览器发起动态请求,浏览器进行页面组装
5.动静分离的几种架构方案
实体机单机部署
统一cache
上CDN(有几个问题:1,失效问题;2,命中率问题;3,发布更新问题;)
五、针对性地处理好系统“热点数据”二八原则
1.热点数据处理
(1)发现静态热点数据的方式
通过报名方式筛选热点商品,后台系统对热点数据进行预处理。
系统预测,系统每天排除top N的商品,后台系统对热点数据进行预处理。
(2)发现动态热点数据的方式
构建一个异步系统,它可以收集交易链路上的各个环节中的中间件产品的热点key,如Nginx、缓存、RPC服务框架等这些中间件。
建立一个热点上报和可以按照需求订阅的热点服务的下发规范,主要目的是通过交易链路上各个系统访问的时间差,把上游系统已经发现的热点同传给下游系统,提前做好保护。
将上游系统收集的热点数据发送到热点服务器,然后下游系统做热点保护。
2.打造热点发现系统注意事项
热点服务后台抓取数据日志采用异步方式
热点服务发现和中间件的热点保护模块并存
热点发下要做到接近实时
3.处理热点数据
(1)优化热点数据
优化热点数据最有效的方法就是缓存热点数据,缓存数据可以用LRU淘汰算法替换。
(2)限制
根据商品id做一致性Hash,放入不同的队列中,防止因某些商品占用太多的服务。
(3)隔离
将这种热点数据隔离出来,不让1%的请求影响到另外99%的请求。
隔离有以下几个层次,业务隔离、系统隔离、数据隔离
六、流量削峰方案
1.排队
把一步的操作变成两步的操作,增加一步起到缓冲的作用。
2.答题
防止部分秒杀器作弊
延缓请求,请求量削峰
3.分层过滤
将动态请求的读数据缓存在web端,过滤掉无效数据;
读数据不做强一致校验;
对写数据进行基于时间的合理分片,过滤掉过期的失效请求;
对写请求做限流保护,将超出系统承载能力的请求过滤掉;
对写数据进行强一致校验,只保留最后有效数据;
七、提高系统性能方案
1.影响性能的因素(服务器性能一般用QPS来衡量)
(1)一次响应的服务端耗时,对性能有影响的是CPU的执行时间
(2)处理请求的线程数,合理的并发线程数
八、减库存设计核心逻辑
1.减库存的3种方式,以及可能存在的问题
(1)下单减库存,下单不付款(大型秒杀系统一般使用下单减库存)
(2)付款减库存,库存超卖
(3)预扣库存(下单后库存保留一定时间)
2.秒杀减库存的极致优化
(1)秒杀商品的减库存逻辑非常单一,可以再缓存系统完成扣减
(2)比较复杂的库存扣减逻辑,要在数据库中完成扣减
九、备选方案的设计
1.高可用建设应该从哪里着手
(1)架构阶段
主要考虑可扩展性和容错性,避免出现单机
(2)编码阶段
主要考虑代码的健壮性,涉及远程调用要设置合理的超时退出
也要对调用的返回结果集有预期,防止返回的结果超出程序处理的范围
(3)测试阶段
保证测试用例的覆盖度
保证最坏的情况发生时,有相应的处理流程
(4)发布阶段
要有紧急的回滚机制
(5)运行阶段
对系统的监控要准确及时
发现问题能准确报警,数据要准确详细,以便排查问题
(6)故障发生
及时止损
及时恢复,并定位原因解决问题