2017-5-26/描述一个高性能高可靠的网站架构——如何设计一个秒杀系统

一、秒杀的应用场景

电商网站的抢购活动、12306网站的抢票、抢红包。

二、秒杀的特点

1、秒杀时大量用户会在同一时间同时进行抢购,网站瞬时访问流量激增。

2、数据库的并发读写冲突以及资源的锁请求冲突非常严重。

3、秒杀一般是访问请求数量远远大于库存数量,只有少部分用户能够秒杀成功。

三、秒杀架构的原则

1、将请求拦截在系统上游,降低下游压力:秒杀系统特点是并发量极大,请求都压倒了后端数据层,但实际秒杀成功的请求数量却很少。所以如果不在前端拦截很可能造成数据库读写锁冲突严重,并发高响应慢,甚至导致死锁,最终请求超时。流量虽大,下单成功的有效流量甚小。

2、利用缓存:利用缓存可极大提高系统读写速度。

3、消息队列:消息队列可以削峰,将拦截大量并发请求,后台业务根据自己的处理能力从消息队列中主动拉取请求消息进行业务处理。

四、秒杀的系统架构

浏览器端(秒杀页面)→ 站点层(网关)→ 服务层 → 数据库层

五、秒杀架构的设计

秒杀系统基于如下原则进行数据分层校验:

1、先做数据的动静分离;

2、将90%的数据缓存在客户端浏览器;

3、将动态请求的读数据Cache在Web端;

4、对读数据不做强一致性校验;

5、对写数据进行基于时间的合理分片;

6、对写请求做限流保护;

7、对写数据进行强一致性校验。

也就是:

1、把大量静态不需要检验的数据放在离用户最近的地方;

2、在前端读系统中检验一些基本信息,如用户是否具有秒杀资格、商品状态是否正常秒杀是否已经结束等;

3、在写数据系统中再校验一些如是否是非法请求,营销等价物是否充足(淘金币等),写的数据一致性如检查库存是否还有等;

4、最后在数据库层保证数据最终准确性,如库存不能减为负数。

六、优化细节

1、秒杀系统独立部署

将秒杀系统独立部署为集群模式,可以避免短时间内的大访问量对现有网站业务造成的冲击,如果需要还可以使用独立域名,使其与网站完全隔离。这样即使秒杀系统崩溃了,也不会对网站造成影响。

2、数据预处理

1)活动页面,有很多视频和图片资源,这些静态资源提前部署在CDN上。

2)将商品本身的属性信息(商品描述、参数、秒杀规则等)这些数据事先存储到数据库中,在容器加载服务启动时,直接加载到本地缓存中当作只读数据,这样可以加速用户访问速度。

3)增加带宽。

3、前端

1)浏览器端

① 禁止重复提交:用户提交之后按钮置灰,禁止重复提交;

② 页面静态化:将活动页面上的所有可以静态的元素(商品描述、参数、详情等)全部写到一个静态页面,不用进行程序的逻辑处理,不需要访问数据库,并尽量减少动态元素。

③ 减少HTTP请求数:主要是合并CSS、JavaScript、图片等。

④ 用户限流:在某一时间段内只允许用户提交一次请求,比如可以采取IP限流。

⑤ 动态生成随机下单页面的URL,避免直接下单:秒杀的游戏规则是到了秒杀才能开始对商品下单购买,在此时间点之前,只能浏览信息不可下单。而下单页面也是一个普通的URL,如果得到这个URL,不用等到秒杀开始就可以下单了。为了避免用户直接访问下单URL,需要将URL动态化,用随机数作为参数,只能秒杀开始的时候才生成。

2)CDN加速

3)反向代理

4、后端

1)站点层(网关层)

针对同一个访问uid,限制访问频率,做页面缓存,几秒内到达站点层的请求,均返回同一页面。

2)服务层

利用缓存应对读、写请求:

大部分请求是查询请求,可以利用缓存分担数据库压力。

对于写请求,可以把数据库中的库存数据转移到Redis缓存中,所有减库存操作都在Redis中进行,然后再通过后台进程把redis中的用户秒杀请求同步到数据库中。可以采用Redis的list数据结构,把每个商品作为key,把用户id作为value,队列的长度就是库存数量。对于每个用户的秒杀,使用 RPUSH key value插入秒杀请求, 当插入的秒杀请求数达到上限时,停止所有后续插入。然后根据先进先出,使用 LPOP key zhuge读取秒杀成功者的用户id,再操作数据库做最终的下订单减库存操作。

② 异步操作,使用消息队列:把请求写到消息队列中,数据库层订阅消息减库存,减库存成功的请求返回秒杀成功,失败的返回秒杀结束。

③ 使用集群:在网站高并发访问的情况下,使用负载均衡技术为一个应用构建一个由多台服务器组成的集群,将并发访问请求分发到多台服务器上处理。

3)数据库层

mysql批量入库提高insert效率。

七、关于超卖

秒杀带来的问题一个是高并发,另一个就是超卖,售出数量多于库存数量。解决超卖问题的方案有两种:

1、采用乐观锁,也就是采用带版本号(Version)更新。

实现的流程为:这个数据所有请求都有资格去修改,但会获得一个该数据的版本号,只有版本号符合的才能更新成功,其他的返回抢购失败。

2、尝试扣减库存,扣减库存成功才会进行下单逻辑。

UPDATE table_name SET n=n-1 WHERE n>1;

扣减库存后进行检查,保证减完不能等于负数。

八、总结

1、将秒杀系统独立部署为集群模式,包括服务器、数据库、缓存等。

2、页面内容静态化,把一些不需要变化的内容写到静态页面,这样不用请求服务器、访问数据库,减轻服务器、数据库的压力。

3、将一些数据事先存储到数据库中,在容器加载服务启动时,直接加载到本地缓存中当作只读数据,加速用户访问速度。

4、增加带宽,将所有静态资源部署在CDN上,减轻网站服务器的压力。

5、使用redis,提高读写速度,分担数据库压力,缓解网站压力。

6、使用消息队列,拦截大量并发请求,后台异步处理,减轻服务器压力。

[参考资料]

秒杀架构分析与实战

关于秒杀的系统架构优化思路

秒杀系统优化方案之缓存、队列、锁设计思路

淘宝大秒系统设计详解

秒杀核心设计(减库存部分)-防超卖与高并发

时间: 2024-10-07 20:44:47

2017-5-26/描述一个高性能高可靠的网站架构——如何设计一个秒杀系统的相关文章

高并发高流量的网站架构设计 (转)

Web2.0的兴起,掀起了互联网新一轮的网络创业大潮.以用户为导向的新网站建设概念,细分了网站功能和用户群,不仅成功的造就了一大批新生的网站,也极大的方便了上网的人们.但Web2.0以用户为导向的理念,使得新生的网站有了新的特点——高并发,高流量,数据量大,逻辑复杂等,对网站建设也提出了新的要求. 本文围绕高并发高流量的网站架构设计问题,主要研究讨论了以下内容: 首先在整个网络的高度讨论了使用镜像网站,CDN内容分发网络等技术对负载均衡带来的便利及各自的优缺点比较.然后在局域网层次对第四层交换技

高并发大型网站架构设计

一个大型的网站网站应该由如下6个子系统组成 负载均衡系统 反向代理系统 Web服务器系统 分布式存储系统 底层服务系统 数据库集群系统 为什么要做高并发系统设计? 事实上,针对于任何单一的网络服务器程序,其可承受的同时连接数目是有理论峰值的,通过C++中对TSocket的定义类型:word,我们可以判 定这个连接理论峰值是65535,也就是说,你的单个服务器程序,最多可以承受6万多的用户同时连接.但是,在实际应用中,能达到一万人的同时连接并能保 证正常的数据交换已经是很不容易了,通常这个值都在2

打造高性能高可靠的块存储系统

块存储系统 分布式存储有出色的性能,可以扛很多故障,能够轻松扩展,所以我们使用Ceph构建了高性能.高可靠的块存储系统,并使用它支撑公有云和托管云的云主机.云硬盘服务. 由于使用分布式块存储系统,避免了复制镜像的过程,所以云主机的创建时间可以缩短到10秒以内,而且云主机还能快速热迁移,方便了运维人员对物理服务器上硬件和软件的维护. 用户对于块存储系统最直观的感受来源于云硬盘服务,现在我们的云硬盘的特点是: 每个云硬盘最大支持 6000 IOPS和170 MB/s的吞吐率,95%的4K随机写操作的

打造高性能高可靠块存储系统

块存储系统 分布式存储有出色的性能,可以扛很多故障,能够轻松扩展,所以我们使用Ceph构建了高性能.高可靠的块存储系统,并使用它支撑公有云和托管云的云主机.云硬盘服务. 由于使用分布式块存储系统,避免了复制镜像的过程,所以云主机的创建时间可以缩短到10秒以内,而且云主机还能快速热迁移,方便了运维人员对物理服务器上硬件和软件的维护. 用户对于块存储系统最直观的感受来源于云硬盘服务,现在我们的云硬盘的特点是: 每个云硬盘最大支持 6000 IOPS和170 MB/s的吞吐率,95%的4K随机写操作的

2017.4.26 慕课网--Java 高并发秒杀API(一)

Java高并发秒杀API系列(一) -----------------业务分析及Dao层 第一章 课程介绍 1.1 内容介绍及业务分析 (1)课程内容 1 SSM框架的整合使用 2 秒杀类系统需求理解和实现 3 常用技术解决高并发问题 (2)SSM框架 (3)为何选择秒杀系统 1 秒杀系统具有典型的"事务"特性 2 秒杀/红包类需求越来越常见 3 面试常用问题 1.3 项目效果演示 第二章 梳理所有技术和搭建工程 2.1 相关技术介绍 2.2 创建项目和依赖 第三章 秒杀业务分析 3.

一个高性能无锁哈希表的设计和实现

无锁哈希表(Lock-Free Hash Table)是多线程编程中的理想数据结构,但是实现以及使用都需要一定的技巧.作者对此做了一个巧妙的设计实现,在现代X86平台上能取得千万次每秒的并发查找/增加/删除操作. 通过考察各种基于CAS原子操作的无锁数据结构实现,目前公认可实现无锁安全的数据结构是数组和单向队列.其他实现都一定程度上受到ABA问题的威胁.数组的实现相对于单向队列要简单,所以无锁hash table理想的选择是数组,对于冲突不拉链.但是如何解决hash冲突呢?基本思想依然是开放寻址

nginx + keepalived 实现高可靠web网站

组网图: 配置信息: 左边nigx 服务器的 /usr/local/nginx/conf/nginx.conf #user  nobody; worker_processes  1; #error_log  logs/error.log; #error_log  logs/error.log  notice; #error_log  logs/error.log  info; #pid        logs/nginx.pid; events { worker_connections  102

千万级PV规模高性能高并发网站架构

防伪码:好久不见,你会不会突然的出现. 客户端:缓存(expires).deflate压缩 缓存服务器:CDN/cache缓存静态内容如:html.jpg.gif.js等 静态web服务器:Apache/nginx静态服务器提供html页面内容 php/java服务器:PHP/JAVA动态内容 数据库缓存服务器:数据库缓存memcache/redis 数据库服务器:MYSQL数据库 数据存储:NFS/HADOOP等 高并发访问的核心原则其实就一句话"把所有的用户访问请求都尽量往前推".

浅谈千万级PV/IP规模高性能高并发网站架构

高并发访问的核心原则其实就一句话“把所有的用户访问请求都尽量往前推”. 如果把来访用户比作来犯的"敌人",我们一定要把他们挡在800里地以外,即不能让他们的请求一下打到我们的指挥部(指挥部就是数据库及分布式存储). 如:能缓存在用户电脑本地的,就不要让他去访问CDN. 能缓存CDN服务器上的,就不要让CDN去访问源(静态服务器)了.能访问静态服务器的,就不要去 访问动态服务器.以此类推:能不访问数据库和存储就一定不要去访问数据库和存储. 说起来很轻松,实际做起来却不容易,但只要稍加努力