Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >秒杀系统设计

秒杀系统设计

作者头像
leobhao
发布于 2022-06-28 10:32:00
发布于 2022-06-28 10:32:00
1.2K0
举报
文章被收录于专栏:涓流涓流

概述

读了极客时间许令波的如何设计秒杀系统后,总结出秒杀系统设计的一些需要注意的点,如何从更多的角度去考量一个架构的设计,保证性能和高可用。

这些经验或者说原则不仅仅适用于秒杀系统,在设计其他系统的时候也有一定的参考性。

秒杀系统的五个原则

总结起来就是:4要,1不要

数据要尽量少

这里的数据值得是用户和系统间传输的数据,包括用户上传给系统的数据和系统返回给用户的数据。

数据少涉及几个方面:

  1. 数据在网络中传输需要时间,数据量越大,网络包耗时越长
  2. 服务器在写网络的时候,一般要进行压缩和字符编码,这些操作比较消耗cpu
  3. 系统依赖的数据要尽量少, 比如和数据库的交互,很容易形成瓶颈
请求数要尽量少

当用户请求页面后,还会有一些其他的额外请求,如静态资源css/js等,每一个请求都会做三次握手,如果资源不在同一个域名下,还会对dns解析形成负担。

可以将多个资源合成一个文件,尽可能对减少请求数

路径要尽量短

路径指的是,用户发出一个请求到返回数据的过程中,经过的中间节点数。

每新增一个节点不但会新增一次网络连接,并且会新增不确定性(多一个节点,就会增加多一个风险点)。缩短请求路径可以增加可用性,也能提升性能。做法一般是将多个互相依赖多应用合并部署在一起,将RPC调用变为本地JVM调用

依赖要尽量少

依赖指的是完成一次用户请求必须依赖的系统或者服务。分为强依赖(必须的依赖)和弱依赖(必要时可以去掉)

如秒杀页面必须依赖商品信息、用户信息,但是其他如优惠券、成交列表等并不是非要不可的信息,这些弱依赖就可以在紧急的时候去掉。

做法一般是将系统按重要程度进行分级,0级系统要尽量减少对1级系统的依赖,防止重要系统被不重要系统拖垮,在极端情况下可以把不重要系统降级,防止拖垮重要系统。

不要有单点

在系统设计中,保证高可用,我们会将每个应用部署多份,作为备份,这也是分布式系统最重要的一点。

避免单点的关键是不要将服务的状态与机器绑定,即将服务无状态化,这样服务就可以在机器中随意移动。将服务与机器状态解耦的方式:与机器相关的配置动态化,服务启动的时候从配置中心拉取,在配置中心设置一些规则来改变这些映射关系。

秒杀系统架构

  1. 秒杀系统单独打造一个系统,与普通的商品购买独立出来,可以单独的作优化
  2. 秒杀系统部署在独立机器集群,秒杀的大流量不会影响到正常的商品购买集群的负载
  3. 热点数据(如库存数据)单独放到缓存系统中,提升读性能
  4. 增加秒杀答题,防止有秒杀器抢单
  5. 页面进行动静分离,让用户秒杀使不在刷新整个界面(又重新加载所有资源),将页面刷新的数据降到最少
  6. 服务端对秒杀商品进行本地缓存,不需要再调用依赖系统的后台服务获取数据,甚至不需要去公共的缓存集群中查询数据,这样不仅可以减少系统调用,而且能够避免压跨公共缓存集群

动静分离

为了提升系统的速度,需要从两个方面去考虑:

  1. 提高单次请求的效率
  2. 减少不必要的请求

动静分离就是针对这个大方向去考量的,尽量只刷新局部数据,分离动态数据和静态数据,每次只请求动态数据,将静态数据缓存起来,客户端大幅度减少了请求的数据量。

缓存静态数据
  1. 针对不会变的静态数据,应缓存到离用户最近的地方。常见的:用户浏览器中,CDN或服务端的Cache中。
  2. 静态改造。相较于普通的数据缓存,静态化改造直接缓存HTTP连接而不是仅仅缓存数据,web服务器根据请求的URL直接取出对应的HTTP响应头和响应体直接返回,不用解析HTTP头也不同重装HTTP协议。与HTTP缓存相关的字段:
  • Pragma+Expires/Cache-Control(强制缓存):program为nocache时,客户端不会读取缓存,每次都会向服务端发请求。Expires来定义缓存的失效时间。但是expires是服务端时间,针对服务端时间与客户端不统一的情况,http1.1使用cache-control来定义缓存过期时间。优先级:Pragma>Expires>Cache-Control
  • Last-Modified/Etag(对比缓存):服务器将资源最后更改时间以Last-modified返回给客户端,客户端请求端时候将这个时间一并传给服务端做检查,如果资源没有被修改过,直接返回304,内容为空。Last-modified无法处理一秒内文件多次修改端情况,http1.1使用ETag字段,通过某种算法给资源计算出唯一标志符,客户端请求时将这个标志一起传给服务端,通过对比判断资源是否已经被修改。
  1. 在哪一层做静态缓存也很重要,不同语言的缓存处理数据的效率也不同。Java不擅长处理大量连接 请求(每个连接消耗的资源多,servelet容器解析http协议慢),所以不必在Java层做静态缓存,相比Java,Web服务器(Nginx,Apache)更擅长处理大量并发静态请求。
如何做静态化改造

分离出动态数据,以商品详情页为例子:

  1. URL唯一化: 如果要缓存整个http连接,需要以唯一的http url作为key
  2. 分离浏览者相关的因素。浏览者相关的因素包括是否登陆以及登陆身份等,这些信息可以通过动态请求获取
  3. 分离时间因素,服务器时间也通过动态请求获取(以防客户端时间和服务端时间不一致)
  4. 去掉Cookie。缓存等静态数据中不含有cookie

通过上述的原则可以分离出动态数据,这样静态数据可以通过缓存来处理,动态数据的处理通常有两种方案:

  1. ESI:在Web代理服务器上做动态内容请求,并将请求插入到静态页面中,当用户拿到页面的时候,已经是一个完整的页面离,这种方式对服务端性能有些影响
  2. CSI: 单独发起异步的JavaScript请求,向服务端获取动态内容。这种方式服务端性能更好,但用户端页面可能会延时,体验稍差

热点数据处理

热点分为热点操作和热点数据:

  • 对于秒杀系统来说,大量刷新页面,大量添加购物车,双十一零点大量下单都属于热点操作。这些操作抽象在系统层面就是读请求和写请求。
  • 热点数据又分为静态热点数据和动态热点数据:
    • 静态热点数据是能够提前预测的热点数据。比如哪些商品可能更热门,历史成交记录也可以找出来
    • 动态热点数据是不能被提前预测的,在系统运行中临时产生的热点数据,比如卖家突然做了广告,导致某个商品变得火热
发现热点数据

静态热点数据可以通过筛选,将可能热卖的商品提前进行预热处理,缓存等

动态热点数据,可以通过大数据进行预测分析发现

处理热点数据

处理热点数据的思路:

  1. 优化。优化热点数据一般是缓存热点数据
  2. 限制。限制的目的是一种保护,比如将访问商品的id做一致性hash,然后根据hash分桶,每个分桶做一个处理队列,这样就可以把热点商品限制在一个请求队列,防止某些热点商品占用太多服务器资源,而使其他商品始终得不到服务器的响应。
  3. 隔离:
    • 业务隔离:秒杀作为一种活动,参与活动的商品就是已知热点,提前做好预热
    • 系统隔离:通过分组部署,与其他普通业务隔离开来
    • 数据隔离:秒杀所调用数据大部分都是热点数据,启用单独的cache和mysql,目的也是不希望影响到其他数据

流量削峰

对于秒杀系统的流量来说,请求高度集中于某一特定时间点,这样某一个瞬间就会有一个特别高的峰值,它对资源对消耗是瞬时的。但对于秒杀这个场景来说,能抢到商品的人数是固定的,并发度越高,无效的请求越多。我们可以在真正下单的时候,设计一些规则,让并发的请求更多的延缓,甚至可以过滤到一些无效的请求。

服务器处理资源是恒定的,我们不能以峰值的要求来配置服务器,这样会让空闲的资源浪费。使用削峰的方式,错峰限行,可以让服务端处理变得更加平稳,也可以节省服务器成本。针对秒杀场景,本质上削峰是为了延缓用户请求的发出,以便减少和过滤掉一些无效请求,遵循了”请求数尽量少”的原则。

削峰一些常见的操作思路:排队、答题、分层过滤。还有一些强制措施,比如限流和机器负载保护等。

排队

对于瞬时流量,最容易想到的是通过消息队列来缓冲,把同步的直接调用转换成异步的间接推送,中间通过一个消息队列来承接瞬时的流量洪峰,在另一端将消息平滑的处理消息。

除了消息队列,类似的排队操作还有:

  1. 线程池加锁等待
  2. 先进先出等内存排队算法的实现方式
  3. 把请求序列化到文件,然后顺序读文件(例如mysql的binlog同步机制)来恢复请求
分层过滤

答题是一种限制手段,为了过滤掉一些机器请求,排队是对发出对请求进行缓冲。分层过滤的思路是用一种漏斗式的设计,来分层过滤掉一些无效请求:

  1. 大部分数据和流量在用户浏览器或CDN上获取,这一层可以拦截大部分数据的读取
  2. 第二层前台系统获取数据尽量走cache(包括强一致性的数据),这一层可以过滤一些无效的请求
  3. 第三层后台系统,主要做数据的二次校验,对系统做好保护和限流,这样数据量和请求就进一步减少
  4. 最后在数据层进行强一致性校验

就像漏洞一样,数据一层一层减少,最后到末端的数据就很少了。

分层过滤的核心思想是在不同层次尽可能的过滤掉无效请求,让达到漏洞末端的才是有效请求,这需要对数据进行分层校验

分层过滤非常适合交易性的写请求,比如减库存或者拼车这种场景,在读的时候需要知道还有没有库存或者是否还有剩余空座位。但是由于库存和座位又是不停变化的,所以读的数据是否一定要非常准确呢?其实不一定,你可以放一些请求过去,然后在真正减的时候再做强一致性保证,这样既过滤一些请求又解决了强一致性读的瓶颈。

减库存设计,防止超卖

在秒杀系统中,超卖是一个原则性问题,假如只秒杀10个商品,确有100个人抢到了,这是一个大损失。

减库存的方式

用户购物过程一般分为两步:下单和付款。在哪个环节减库存,是一个考量,一般分为几种方式:

  1. 下单减库存:即当买家下单后,在商品的总库存中减去买家购买数量。下单减库存是最简单的减库存方式,也是控制最精确的一种,下单时直接通过数据库的事务机制控制商品库存,这样一定不会出现超卖的情况。但是你要知道,有些人下完单可能并不会付款。
  2. 付款减库存:即买家下单后,并不立即减库存,而是等到有用户付款后才真正减库存,否则库存一直保留给其他买家。但因为付款时才减库存,如果并发比较高,有可能出现买家下单后付不了款的情况,因为可能商品已经被其他人买走了。
  3. 这种方式相对复杂一些,买家下单后,库存为其保留一定的时间(如 10 分钟),超过这个时间,库存将会自动释放,释放后其他买家就可以继续购买。在买家付款前,系统会校验该订单的库存是否还有保留:如果没有保留,则再次尝试预扣;如果库存不足(也就是预扣失败)则不允许继续付款;如果预扣成功,则完成付款并实际地减去库存。
减库存中可能存在的问题

如果使用下单减库存,很多人恶意下单后并不付款,这样可能导致恶意下单,从而影响卖家销售。

如果使用付款减库存,又可能导致超卖,因为下单成功的人数很可能超过真正的库存数,这样很多买家下单成功确无法付款,购物体验极差。

针对上述情况,将下单减库存和付款减库存两者结合起来,下单时先预扣,在规定时间内不付款在释放库存,即采用预扣库存的方式会一定程度上缓解上面的问题。

参考资料

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-06-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
6000多字 | 秒杀系统设计注意点【理论】
首先是指用户请求的数据能少就少。请求的数据包括上传给系统的数据和系统返回给用户的数据(通常就是网页)。
田维常
2020/12/14
4320
如何设计一个秒杀系统
秒杀本质是要求一个瞬时高发下的承压系统,这也是其区别于其他业务的核心场景。对日常系统秒杀产生的问题逐一进行拆解分类,秒杀对应到架构设计,其实就是高可用、一致性和高性能的要求。关于秒杀系统的设计思考,本文即基于此 3 层依次推进,简述如下——
终有链响
2024/07/29
1730
如何设计一个秒杀系统
【经验】一个秒杀系统的设计思考
秒杀大家都不陌生。自2011年首次出现以来,无论是双十一购物还是 12306 抢票,秒杀场景已随处可见。简单来说,秒杀就是在同一时刻大量请求争抢购买同一商品并完成交易的过程。
良月柒
2019/12/09
9610
【经验】一个秒杀系统的设计思考
在线面试:如何设计一个秒杀系统?
秒杀大家都不陌生。自2011年首次出现以来,无论是双十一购物还是 12306 抢票,秒杀场景已随处可见。简单来说,秒杀就是在同一时刻大量请求争抢购买同一商品并完成交易的过程。从架构视角来看,秒杀系统本质是一个高性能、高一致、高可用的三高系统。而打造并维护一个超大流量的秒杀系统需要进行哪些关注,就是本文讨论的话题。
田维常
2022/04/19
9830
在线面试:如何设计一个秒杀系统?
如何设计一个秒杀系统
秒杀已经成为电商不可缺少的一步分了,所谓 买到就是赚到,可以成功吸引到一大堆用户,那程序员面对这些用户该怎么办呢。我们该如何设计秒杀呢?
憧憬博客
2020/10/09
8020
如何设计一个秒杀系统?
这篇分享源自之前购买的极客时间课程《如何设计一个秒杀系统》,以及书籍《亿级流量网站架构核心技术》。
BookSea
2024/06/18
3060
如何设计一个秒杀系统?
面试官问我:如何设计一个秒杀场景?
从读者的描述,可以看出高并发处理的经验,在面试中占据着举足轻重的地位,关于高并发相关的面试题,一直都是面试热题,因为这类面试题能够更加直观地体现候选人的技术水平与深度。如何解决高并发场景下的问题,永远都不会过时。
张乘辉
2021/06/10
1.7K0
面试官问我:如何设计一个秒杀场景?
如何设计一个秒杀系统-极客课程笔记
感兴趣的朋友可以去购买,课程地址:如何设计一个秒杀系统 (geekbang.org)
OwenZhang
2022/01/05
6130
如何设计一个秒杀系统-极客课程笔记
Java编程解析—淘宝大秒杀系统设计
最初的秒杀系统的原型是淘宝详情上的定时上架功能,由于有些卖家为了吸引眼球,把价格压得很低。但这给的详情系统带来了很大压力,为了将这种突发流量隔离,才设计了秒杀系统,文章主要介绍大秒系统以及这种典型读数据的热点问题的解决思路和实践经验。
慕容千语
2019/06/06
1.2K0
Java编程解析—淘宝大秒杀系统设计
淘宝大秒系统设计详解
1. 一些数据2. 热点隔离3. 动静分离4. 基于时间分片削峰5. 数据分层校验6. 实时热点发现7. 关键技术优化点7.1 Java处理大并发动态请求优化7.2 同一商品大并发读问题7.3 同一数据大并发更新问题8. 大促热点问题思考
芋道源码
2018/12/13
6220
淘宝大秒系统设计详解
如何设计属于你自己的秒杀系统?
其实,整个秒杀的业务场景并不复杂,可即查看参与秒杀的商品信息,加上购买和支付的动作,如下图所示。
Rude3Knife的公众号
2022/12/10
1.1K0
如何设计属于你自己的秒杀系统?
秒杀系统之一致性
秒杀系统中,库存是个关键数据,卖不出去是个问题,超卖更是个问题。秒杀场景下的一致性问题,主要就是库存扣减的准确性问题。
终有链响
2024/07/29
2020
秒杀系统设计
构建一个高并发、高可用的分布式微服务秒杀系统需要从架构设计、流量控制、数据一致性、缓存策略、数据库优化等多个方面综合考虑。以下是核心设计思路和关键技术点:
jack.yang
2025/04/05
3390
秒杀系统设计
让你负责秒杀系统架构,应该怎么搞?
比如小米秒杀,三星秒杀都是瞬时抢走十几万台手机,天猫最快破亿的一个旗舰店,双十一峰值可达到60w以上的qps。后端的k-v集群峰值可达几千万qps,单机可达到30w qps,这些主要是读流量,写流量则小的多,比如对应时间点的减库存写操作也就几kqps。
春哥大魔王
2019/09/17
4800
让你负责秒杀系统架构,应该怎么搞?
秒杀系统瞬时百万并发流量的六种应对之道
作者:冰河 星球:http://m6z.cn/6aeFbs 博客:https://binghe.gitcode.host 文章汇总:https://binghe.gitcode.host/md/all/all.html 源码获取地址:https://t.zsxq.com/0dhvFs5oR 备注:本文节选自 冰河技术 知识星球《Seckill秒杀系统》专栏,文末有福利! 沉淀,成长,突破,帮助他人,成就自我。 本章难度:★★★☆☆ 本章重点:全面阐述建设秒杀系统挑战的应对之道,知己知彼,方案了然于胸,自然
博文视点Broadview
2023/05/19
5020
秒杀系统瞬时百万并发流量的六种应对之道
如何设计一个秒杀系统?
于是,秒杀系统一般会引入MQ、Redis、MySQL、Nginx等中间件,需要对每个中间件进行高性能、高并发、高可用的分析。
用户7353950
2022/06/23
4650
秒杀团购如何做到抗住高流量?
这里我以我做的一个最有意思的营销活动,给大家介绍一下,不涉及技术,后面出案例会以此为案例而已,看技术可以跳过,我这个活动叫做《周期循环购》,这个活动可以设置好参与的商品,然后支持设置活动总的有效时间之外呢,我们还支持让你选择周一到周日哪几天是开团天,每个开团日再进行设置哪几个时间段为开团时段,然后还支持设置商品在每个时段的库存是多少,那么其实在这里看,团购对于我来说就是一个产品的概念(SPU),而我的营销活动限制的才是真正的库存(SKU),另外这个又涉及到周期性库存的概念,每天每个事件段都有一个自己的独立库存,这比单一的商品库存要复杂许多许多。
名字是乱打的
2021/12/24
9960
秒杀系统之设计方向
秒杀本质是要求一个瞬时高发下的承压系统,这也是其区别于其他业务的核心场景。对日常系统秒杀产生的问题逐一进行拆解分类,秒杀对应到架构设计,其实就是高可用、一致性和高性能的要求。关于秒杀系统的设计思考,本文即基于此 3 层依次推进,简述如下——
终有链响
2024/07/29
1310
秒杀系统之设计方向
秒杀系统解决方案
感谢于霆霖的投稿,本文摘自:http://yutinglin.cn/2017/08/01/秒杀系统解决方案/ 我看了二十篇左右的秒杀系统设计及解决方案的文章,从架构、产品、前端、后端四个层面分别总结了一些解决方案。 要点总结: 1.架构:扩容,业务分离,数据分离 2.产品:下单按钮控制,秒杀答题削峰,简化页面设计 3.前端:限流(反作弊) 静态化 4.后端:内存 队列 一、秒杀一般会带来2个问题: 1、高并发 比较火热的秒杀在线人数都是10w起的,如此之高的在线人数对于网站架构从前到后都是一种考验。 2、超
程序猿DD
2018/02/01
1.7K0
高并发: 流量削峰 与 服务端优化
如果看过秒杀系统的流量监控图的话,会发现它是一条直线,就在秒杀开始那一秒是一条很直很直的线,这是因为秒杀请求在时间上高度集中于某一特定的时间点。这样一来,就会导致一个特别高的流量峰值,它对资源的消耗是瞬时的
BUG弄潮儿
2021/09/10
1.4K0
高并发: 流量削峰 与 服务端优化
相关推荐
6000多字 | 秒杀系统设计注意点【理论】
更多 >
LV.1
点掌财经Developer
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档