秒杀场景的设计思考

秒杀场景的设计思考

在学习Redis的之后,一个绕不开的话题就是秒杀系统的设计。本文将从下面👇🏻几个方面展开一下个人简单的理解:

  • 秒杀场景的介绍
  • 设计的核心思路
  • 怎么限流、削峰、异步
  • planB
  • 总结

秒杀场景的介绍

秒杀场景是大家常说的高并发场景,但是实际上其与单纯的高并发还有一点不同,主要区别就是其流量来的猛增,几乎是一个垂直的增长,而非线性增长的并发。

其具有如下特点:

  • 瞬时高并发
  • 读多写少
  • 不能超卖

设计的核心思路

在解决系统架构的问题上,我们设计可以参考三要和一不要的原则,从一些通用性的角度提高一些系统健壮性:

  • 要:要减少请求数据量;要减少请求次数;要减少依赖
  • 不要:不要有“单点”

要减少请求数据量:后台返回前台的数据一般分为动态数据和静态数据,对于秒杀场景,我们可以考虑动静分离,对于不怎么会变化的数据,我们可以用cache、cdn等手段来直接处理,避免对后端资源的占用;对于库存这样的动态数据,我们才真正的去调用关键的接口和服务器。

要减少请求的次数:减少请求数最常用的一个实践就是合并CSS和JavaScript文件,把多个JavaScript文件合并成一个文件。这种方式在服务端仍然是单个文件各自存放,只是服务端会有一个组件解析这个URL,然后动态把这些文件合并起来一起返回。

有些同学会感觉这个第二点和第一点不是冲突的吗?
第一点说要减少请求数据量,所以要使用动静结合,第二点又说要减少请求的次数,和第一点不是矛盾了吗?实际上确实有一些矛盾的地方,就看取舍了,不同场景的考虑不一样,在秒杀场景来说,动静分离的好处肯定是比 动静合并一起返回的带来的收益更大的。

要减少依赖:这点很好理解。我们在设计系统的时候在能满足需求和拓展性等能力的基础上,系统的架构约简单越好。此外,在架构设计的时候,我们必须要很好的梳理清楚系统的强弱依赖,这样才能在发生系统瓶颈或者异常的情况下及时定位到问题并解决。

不要有“单点” :在分布式的架构设计的时候,我们的一个大忌就是“单点”问题,而解决的方法就是一般来说就是服务无状态话。服务无状态之后,我们可以非常方便的进行服务的扩容和迁移等。当然,对于数据库这样保存数据的服务很难(没办法)做到无状态话,这时,我们一般会采用冗余备份等方法增强其可靠性。

如何防止瞬时高并发

主要三个措施:缓存预热、流量限制。

我们也可以从事前、事中、事后的时间轴的角度来理解:事前:缓存预热;事后:流量限制、以及一些常用手段(限流、削峰、异步);事后:并发较低,主要考虑对库存的一些处理。

  1. 缓存预热

我们可以对热点数据进行预热,热点数据就是指那些被秒杀的商品的一些信息。可以在秒杀开始之前将这些热点数据提前加载在缓存中。

对于提前并不能得知哪些数据是热点的情况,我们可以考虑进行一些动态的数据分析来获取热key,比如京东开源的hotkey框架。

  1. 流量限制

在秒杀场景中,我们最有可能出现性能瓶颈的地方是用于控制库存的DB,因此需要尽量控制进入DB中的并发量。

可以从两个角度考虑:非后端角度降低并发量 + 后端角度降低并发量。

非后端角度限制并发

非后端角度降低并发量指的是在流量打到后端处理秒杀的服务器之前就降低并发量,常见的角度为:

1.人为增加流程:比如说答题系统。答题系统的增加一方面来说由于人的答题速度不一致,一定程度上是分散了并发数量,另一方面来说也可以一定程度上防止用户使用作弊器的行为;又比如说前端通过限频降低并发数量,让用户点击的时候实际上不是每次点击都真正有效。

2.分层过滤:通过分层的措施,每一层减少一部分流量。如下图所示,真正访问到DB中的并发量相对于用户访问量来说已经是一个很少的比例了。

image

后端角度限制并发

后端限制并发就是一些通用的手段了,常见的有:

  • 使用mq进行异步削峰
  • 使用线程池限制并发数量
  • 使用缓存(使用缓存当然要考虑一致性问题,在秒杀场景就是“超卖"问题,文章后面关于超卖|库存如何扣减会讨论)

补充

库存何时扣减

库存的扣减一般来说有3种时机:

  1. 下单时扣减库存:买家只要完成下单,立即减扣商品库存,这种方式实现是最简单而且也是最精准的,通常可以在下单时利用数据库事务能力即可保证减扣库存的准确性,但需要考虑买家下单后不付款的情况。
  2. 付款时扣减库存:卖家下单的时候不扣减库存,付款的时候才扣减库存。好处是不需要考虑下单不付款的库存回填的情况,坏处则是并发量大会出现大量用户能下单,但是付款无法完成(显示库存不足 )。
  3. 结合前2种方案,下单时保留一定时间的库存:下单的时候扣减库存,如果用户30min时间内没有完成付款,那么就释放库存,其它用户可以继续抢购。

可以结合平时网上下单的步骤想一下,我们下单需要哪几个步骤:1.点击下单;2.填写地址并付款。

根据在淘宝购买商品的经验,综合用户体验和实际架构,一般来说选择方案3。

关于超卖|库存如何扣减

库存是放在MySQL中进行处理的,因此库存扣减判断的最终参考指标是:利用数据库的本地事务机制进行对库存的减扣,比如使用 where 库存 >0不满足就回滚。

但是在实际的秒杀场景架构中,肯定是会引入 Redis这样的缓存。
在引入缓存之后,我们就必须考虑缓存的一致性问题,一个很有意思的一点是:在秒杀场景中一般来说我们不需要强保证缓存和数据库中关于库存数据的一致性。
即,我们可以允许一定量的在Redis这一层的“超卖”,Redis“超卖”后,超卖的请求的数量不会太大,这些数量可以交给MySQL进行处理。

上面一段中提到“这些数量可以交给MySQL进行处理”,那么究竟多少数据可以交给MySQL处理呢?
实际上这就体现出压测的重要性了,这些请求究竟并发量由多少,MySQL可以承载多少理论分析只能有个指导值,具体有多少必须跑一跑压测才知道!

planB

前面我们提到了很多关于秒杀场景的设计,包括如何减少后端压力、如何设计库存扣减等等来保证系统的高性能。
然而,无论再精细的设计也只能保证系统尽可能健壮,因此我们在设计的时候必须考虑高可用方案。

关于如何设计高可用的方案,就是一个比较复杂的话题了,而且需要根据不同的系统和性能指标要求有不同的取舍,这里大概列出需要考虑的方面:

  • 防止单点问题

  • 防止影响扩大:隔离

  • 如何降级、熔断

总结

秒杀场景是一个高可用场景中的典型类型,其拥有:高并发、读多写少、严格数据保证(不能超卖)的特点。
首先的思路是降低直接打入DB的并发量,可以考虑分层降低流量和增加步骤等操作降低并发。
其次库存扣减时机和超卖问题也有很多值得讨论的地方。
最后,再复杂的设计也有可能发生意外,因此我们必须考虑高可用的方案(planb)。

此外,在实际的场景中,除了正常的请求之外,往往我们还要考虑一些其他东西,比如说:灰产、用户恶意锁单等情况。

主要参考:

  • geektime专栏:06 | 秒杀系统“减库存”设计的核心逻辑-如何设计一个秒杀系统-极客时间
  • 后端进阶:面试官问我:如何设计一个秒杀场景?-阿里云开发者社区
  • 面试必备:秒杀场景九个细节-腾讯云开发者社区-腾讯云 , 这个方案很详细,但是讲的很乱,想了解细节可以看看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/944589.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

秒鲨后端之MyBatis【2】默认的类型别名、MyBatis的增删改查、idea中设置文件的配置模板、MyBatis获取参数值的两种方式、特殊SQL的执行

别忘了请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01;! ! ! 下篇更新&#xff1a; 秒鲨后端之MyBatis【3】自定义映射resultMap、动态SQL、MyBatis的缓存、MyBatis的逆向工程、分页插件。 默认的类型别名 MyBatis的增删改查 添加 <!--int insertUs…

2024年12月29日Github流行趋势

项目名称&#xff1a;cobalt 项目地址url&#xff1a;https://github.com/imputnet/cobalt项目语言&#xff1a;Svelte历史star数&#xff1a;22882今日star数&#xff1a;1049项目维护者&#xff1a;wukko, dumbmoron, Snazzah, lexito-o, KwiatekMiki项目简介&#xff1a;保存…

【LLM】OpenAI 的DAY12汇总和o3介绍

note o3 体现出的编程和数学能力&#xff0c;不仅达到了 AGI 的门槛&#xff0c;甚至摸到了 ASI&#xff08;超级人工智能&#xff09;的边。 Day 1&#xff1a;o1完全版&#xff0c;开场即巅峰 12天发布会的开场即是“炸场级”更新——o1完全版。相比此前的预览版本&#x…

国内独立开发者案例及免费送独立开发蓝图书

独立开发者在国内越来越受到关注&#xff0c;他们追求的是一种自由且自给自足的工作状态。 送这个&#xff1a; 少楠light&#xff08;Flomo、小报童、如果相机&#xff09;&#xff1a;他们是独立开发者的典范&#xff0c;不仅开发了多款产品&#xff0c;还坚信“剩者为王”…

【js】记录预览pdf文件

接口调用拿到pdf的文件流&#xff0c;用blob处理这个文件流拿到url&#xff0c;使用window.open跳转新的窗口进行预览 api({dataType: blob, }).then(res >{if(res.code 0){this.previewPDF(res,application/pdf;charsetutf-8,pdf文件名)} })previewPDF (res, type, fname…

Vue3 +Element-Plus el-select下拉菜单样式(局部生效)

下拉框代码 <el-selectclass"buttons-switch-group select-hub":teleported"false"style"width: 120px"v-model"queryParam.type"placeholder"请选择"size"mini"change"loadData"><el-option…

手机h5加桌面图标

手机h5应用1&#xff0c;网址浏览器添加到桌面&#xff0c;修改图标 关键代码 <!-- 手机h5加桌面图标 --> <!-- 安卓平台 chrome --> <link relapple-touch-icon-precomposed href<% BASE_URL %>logonew.png> <meta name"mobile-web-app-capab…

从家谱的层级结构 - 组合模式(Composite Pattern)

组合模式&#xff08;Composite Pattern&#xff09; 组合模式&#xff08;Composite Pattern&#xff09;组合模式概述组合模式涉及的角色talk is cheap&#xff0c; show you my code总结 组合模式&#xff08;Composite Pattern&#xff09; 组合模式&#xff08;Composite…

JavaEE 3大组件 Listener Servlet Filter

1. Listener不熟悉 2. Servlet Servlet: Server Applet&#xff0c;翻译为运行在服务端的Java小程序&#xff0c;是sun公司提供一套规范( 接口 )&#xff0c;用来定义我们的代码怎么写才能被tomcat识别。 本质&#xff1a;接口&#xff0c;一个类想要被tomcat正确识别&…

Debian-linux运维-docker安装和配置

腾讯云搭建docker官方文档&#xff1a;https://cloud.tencent.com/document/product/213/46000 阿里云安装Docker官方文档&#xff1a;https://help.aliyun.com/zh/ecs/use-cases/install-and-use-docker-on-a-linux-ecs-instance 天翼云常见docker源配置指导&#xff1a;htt…

探索PyTorch:从入门到实践的demo全解析

探索PyTorch:从入门到实践的demo全解析 一、环境搭建:PyTorch的基石(一)选择你的“利器”:安装方式解析(二)步步为营:详细安装步骤指南二、基础入门demo:点亮第一盏灯(一)张量操作:深度学习的“积木”(二)自动求导:模型学习的“幕后英雄”三、数据处理demo:喂饱…

vulnhub靶机billu_b0x精讲

靶机下载 https://www.vulnhub.com/entry/billu-b0x,188/ 信息收集 扫描存活主机 nmap -sP 192.168.73.0/24 192.168.73.141为目标主机&#xff0c;对其进行进一步信息收集 端口扫描 nmap --min-rate10000 -p- 192.168.73.141 目标只开放了22和80端口 针对端口进行TCP探…

碰一碰发视频矩阵系统源码搭建,支持OEM

一、引言 随着短视频的火爆发展&#xff0c;碰一碰发视频的矩阵系统逐渐受到关注。这种系统能够实现用户通过碰一碰设备&#xff08;如 NFC 标签&#xff09;快速触发视频的发布&#xff0c;在营销推广、互动体验等领域有着广泛的应用前景。本文将详细介绍碰一碰发视频矩阵系统…

使用Kubernetes部署MySQL+WordPress

目录 前提条件 部署MySQL和WordPress 编写yaml文件 应用yaml文件 存在问题及解决方案 创建PV(持久化卷) 创建一个PVC(持久化卷声明) 部署添加PVC 查看PV对应的主机存储 删除资源 查看资源 删除deployment和service 查看主机数据 删除PVC和PV 删除主机数据 前提条…

Python笔记(6)-文件及IO操作

文件的基本操作 python操作文件的步骤&#xff1a; 1、打开文件&#xff1a; 变量名open(filename,mode,encoding) 2、操作文件&#xff1a; 变量名.read() 变量名.writer(s) 3、关闭文件&#xff1a; 变量名.close() def my_write():#1、&#xff08;创建&#xff09;…

windows系统下使用cd命令切换到D盘的方法

windows系统下使用cd命令切换到D盘的方法 系统环境配置 win10系统原装C盘后期自己安装的硬盘D盘 python3.8安装在D盘中 问题说明 winR打开终端&#xff0c;使用 cd d:命令&#xff0c;无法将当前目录切换到D盘 解决方法 方法一&#xff1a;使用下面这条命令 cd /d d:运…

iOS 苹果开发者账号: 查看和添加设备UUID 及设备数量

参考链接&#xff1a;苹果开发者账号下添加新设备UUID - 简书 如果要添加新设备到 Profiles 证书里&#xff1a; 1.登录开发者中心 Sign In - Apple 2.找到证书设置&#xff1a; Certificate&#xff0c;Identifiers&Profiles > Profiles > 选择对应证书 edit &g…

香橙派5Plus启动报错bug: spinlock bad magic on cpu#6, systemd-udevd/443

一、问题 如图&#xff1a; 接上调试串口&#xff0c;每次启动都会报错。不过使用过程中没有发现有什么影响。 百度查阅&#xff0c;有一位博主提到&#xff0c;但是没有细说解决方案&#xff1a; spinlock变量没有初始化_spinlock bad magic on-CSDN博客https://blog.csdn.n…

小程序配置文件 —— 13 全局配置 - window配置

全局配置 - window配置 这里讲解根目录 app.json 中的 window 字段&#xff0c;window 字段用于设置小程序的状态栏、导航条、标题、窗口背景色&#xff1b; 状态栏&#xff1a;顶部位置&#xff0c;有网络信号、时间信息、电池信息等&#xff1b;导航条&#xff1a;有一个当…

UI页面布局分析(4)- 贵族 特权分页列表

引言 在现在移动应用中&#xff0c;展示用户特权的UI设计不仅是吸引用户的关键手段&#xff0c;更是提升产品体验的重要部分。特别是在直播场景中&#xff0c;贵族特权作为一种高价值用户身份的象征&#xff0c;通常需要通过精致的页面和流程的交互来突出其重要性和独特性。 …