架构师之道 秒杀系统优化思路

2023-11-15

本文曾在“架构师之路”上发布过,近期支援Qcon-AS大会,在微信群里分享了该话题,故对原文进行重新整理与发布。

一、秒杀业务为什么难做


1)im系统,例如qq或者微博,每个人都读自己的数据(好友列表、群列表、个人信息);
2)微博系统,每个人读你关注的人的数据,一个人读多个人的数据;
3)秒杀系统,库存只有一份,所有人会在集中的时间读和写这些数据,多个人读一个数据。

例如:小米手机每周二的秒杀,可能手机只有1万部,但瞬时进入的流量可能是几百几千万。

又例如:12306抢票,票是有限的,库存一份,瞬时流量非常多,都读相同的库存。读写冲突,锁非常严重,这是秒杀业务难的地方。那我们怎么优化秒杀业务的架构呢?

二、优化方向


优化方向有两个(今天就讲这两个点):

(1)将请求尽量拦截在系统上游(不要让锁冲突落到数据库上去)。传统秒杀系统之所以挂,请求都压倒了后端数据层,数据读写锁冲突严重,并发高响应慢,几乎所有请求都超时,流量虽大,下单成功的有效流量甚小。以12306为例,一趟火车其实只有2000张票,200w个人来买,基本没有人能买成功,请求有效率为0。

(2)充分利用缓存,秒杀买票,这是一个典型的读多写少的应用场景,大部分请求是车次查询,票查询,下单和支付才是写请求。一趟火车其实只有2000张票,200w个人来买,最多2000个人下单成功,其他人都是查询库存,写比例只有0.1%,读比例占99.9%,非常适合使用缓存来优化。好,后续讲讲怎么个“将请求尽量拦截在系统上游”法,以及怎么个“缓存”法,讲讲细节。

三、常见秒杀架构


常见的站点架构基本是这样的(绝对不画忽悠类的架构图)

(1)浏览器端,最上层,会执行到一些JS代码
(2)站点层,这一层会访问后端数据,拼html页面返回给浏览器
(3)服务层,向上游屏蔽底层数据细节,提供数据访问
(4)数据层,最终的库存是存在这里的,mysql是一个典型(当然还有会缓存)

这个图虽然简单,但能形象的说明大流量高并发的秒杀业务架构,大家要记得这一张图。后面细细解析各个层级怎么优化。

四、各层次优化细节


第一层,客户端怎么优化(浏览器层,APP层)

问大家一个问题,大家都玩过微信的摇一摇抢红包对吧,每次摇一摇,就会往后端发送请求么?回顾我们下单抢票的场景,点击了“查询”按钮之后,系统那个卡呀,进度条涨的慢呀,作为用户,我会不自觉的再去点击“查询”,对么?继续点,继续点,点点点。。。有用么?平白无故的增加了系统负载,一个用户点5次,80%的请求是这么多出来的,怎么整?

(a)产品层面,用户点击“查询”或者“购票”后,按钮置灰,禁止用户重复提交请求;

(b)JS层面,限制用户在x秒之内只能提交一次请求;

APP层面,可以做类似的事情,虽然你疯狂的在摇微信,其实x秒才向后端发起一次请求。这就是所谓的“将请求尽量拦截在系统上游”,越上游越好,浏览器层,APP层就给拦住,这样就能挡住80%+的请求,这种办法只能拦住普通用户(但99%的用户是普通用户)对于群内的高端程序员是拦不住的。firebug一抓包,http长啥样都知道,js是万万拦不住程序员写for循环,调用http接口的,这部分请求怎么处理?

第二层,站点层面的请求拦截

怎么拦截?怎么防止程序员写for循环调用,有去重依据么?ip?cookie-id?…想复杂了,这类业务都需要登录,用uid即可。在站点层面,对uid进行请求计数和去重,甚至不需要统一存储计数,直接站点层内存存储(这样计数会不准,但最简单)。一个uid,5秒只准透过1个请求,这样又能拦住99%的for循环请求。

5s只透过一个请求,其余的请求怎么办?缓存,页面缓存,同一个uid,限制访问频度,做页面缓存,x秒内到达站点层的请求,均返回同一页面。同一个item的查询,例如车次,做页面缓存,x秒内到达站点层的请求,均返回同一页面。如此限流,既能保证用户有良好的用户体验(没有返回404)又能保证系统的健壮性(利用页面缓存,把请求拦截在站点层了)。

页面缓存不一定要保证所有站点返回一致的页面,直接放在每个站点的内存也是可以的。优点是简单,坏处是http请求落到不同的站点,返回的车票数据可能不一样,这是站点层的请求拦截与缓存优化。

好,这个方式拦住了写for循环发http请求的程序员,有些高端程序员(黑客)控制了10w个肉鸡,手里有10w个uid,同时发请求(先不考虑实名制的问题,小米抢手机不需要实名制),这下怎么办,站点层按照uid限流拦不住了。
 

第三层 服务层来拦截(反正就是不要让请求落到数据库上去)

服务层怎么拦截?大哥,我是服务层,我清楚的知道小米只有1万部手机,我清楚的知道一列火车只有2000张车票,我透10w个请求去数据库有什么意义呢?没错,请求队列!

对于写请求,做请求队列,每次只透有限的写请求去数据层(下订单,支付这样的写业务)

1w部手机,只透1w个下单请求去db

3k张火车票,只透3k个下单请求去db

如果均成功再放下一批,如果库存不够则队列里的写请求全部返回“已售完”。


对于读请求,怎么优化?cache抗,不管是memcached还是redis,单机抗个每秒10w应该都是没什么问题的。如此限流,只有非常少的写请求,和非常少的读缓存mis的请求会透到数据层去,又有99.9%的请求被拦住了。
 

当然,还有业务规则上的一些优化。回想12306所做的,分时分段售票,原来统一10点卖票,现在8点,8点半,9点,...每隔半个小时放出一批:将流量摊匀。

其次,数据粒度的优化:你去购票,对于余票查询这个业务,票剩了58张,还是26张,你真的关注么,其实我们只关心有票和无票?流量大的时候,做一个粗粒度的“有票”“无票”缓存即可。

第三,一些业务逻辑的异步:例如下单业务与 支付业务的分离。这些优化都是结合 业务 来的,我之前分享过一个观点“一切脱离业务的架构设计都是耍流氓”架构的优化也要针对业务。

第四层 最后是数据库层

浏览器拦截了80%,站点层拦截了99.9%并做了页面缓存,服务层又做了写请求队列与数据缓存,每次透到数据库层的请求都是可控的。db基本就没什么压力了,闲庭信步,单机也能扛得住,还是那句话,库存是有限的,小米的产能有限,透这么多请求来数据库没有意义。

全部透到数据库,100w个下单,0个成功,请求有效率0%。透3k个到数据,全部成功,请求有效率100%。

五、总结


上文应该描述的非常清楚了,没什么总结了,对于秒杀系统,再次重复下我个人经验的两个架构优化思路:
(1)尽量将请求拦截在系统上游(越上游越好);

(2)读多写少的常用多使用缓存(缓存抗读压力);

浏览器和APP:做限速

站点层:按照uid做限速,做页面缓存

服务层:按照业务做写请求队列控制流量,做数据缓存

数据层:闲庭信步

并且:结合业务做优化

六、Q&A


问题1、按你的架构,其实压力最大的反而是站点层,假设真实有效的请求数有1000万,不太可能限制请求连接数吧,那么这部分的压力怎么处理?

答:每秒钟的并发可能没有1kw,假设有1kw,解决方案2个:

(1)站点层是可以通过加机器扩容的,最不济1k台机器来呗。
(2)如果机器不够,抛弃请求,抛弃50%(50%直接返回稍后再试),原则是要保护系统,不能让所有用户都失败。
 

问题2、“控制了10w个肉鸡,手里有10w个uid,同时发请求” 这个问题怎么解决哈?

答:上面说了,服务层写请求队列控制

问题3:限制访问频次的缓存,是否也可以用于搜索?例如A用户搜索了“手机”,B用户搜索“手机”,优先使用A搜索后生成的缓存页面?

答:这个是可以的,这个方法也经常用在“动态”运营活动页,例如短时间推送4kw用户app-push运营活动,做页面缓存。

问题4:如果队列处理失败,如何处理?肉鸡把队列被撑爆了怎么办?

答:处理失败返回下单失败,让用户再试。队列成本很低,爆了很难吧。最坏的情况下,缓存了若干请求之后,后续请求都直接返回“无票”(队列里已经有100w请求了,都等着,再接受请求也没有意义了)

问题5:站点层过滤的话,是把uid请求数单独保存到各个站点的内存中么?如果是这样的话,怎么处理多台服务器集群经过负载均衡器将相同用户的响应分布到不同服务器的情况呢?还是说将站点层的过滤放到负载均衡前?

答:可以放在内存,这样的话看似一台服务器限制了5s一个请求,全局来说(假设有10台机器),其实是限制了5s 10个请求,解决办法:

1)加大限制(这是建议的方案,最简单)
2)在nginx层做7层均衡,让一个uid的请求尽量落到同一个机器上
 

问题6:服务层过滤的话,队列是服务层统一的一个队列?还是每个提供服务的服务器各一个队列?如果是统一的一个队列的话,需不需要在各个服务器提交的请求入队列前进行锁控制?

答:可以不用统一一个队列,这样的话每个服务透过更少量的请求(总票数/服务个数),这样简单。统一一个队列又复杂了。

问题7:秒杀之后的支付完成,以及未支付取消占位,如何对剩余库存做及时的控制更新?

答:数据库里一个状态,未支付。如果超过时间,例如45分钟,库存会重新会恢复(大家熟知的“回仓”),给我们抢票的启示是,开动秒杀后,45分钟之后再试试看,说不定又有票哟~

问题8:不同的用户浏览同一个商品 落在不同的缓存实例显示的库存完全不一样 请问老师怎么做缓存数据一致或者是允许脏读?

答:目前的架构设计,请求落到不同的站点上,数据可能不一致(页面缓存不一样),这个业务场景能接受。但数据库层面真实数据是没问题的。

问题9:就算处于业务把优化考虑“3k张火车票,只透3k个下单请求去db”那这3K个订单就不会发生拥堵了吗?

答:(1)数据库抗3k个写请求还是ok的;(2)可以数据拆分;(3)如果3k扛不住,服务层可以控制透过去的并发数量,根据压测情况来吧,3k只是举例;

问题10;如果在站点层或者服务层处理后台失败的话,需不需要考虑对这批处理失败的请求做重放?还是就直接丢弃?

答:别重放了,返回用户查询失败或者下单失败吧,架构设计原则之一是“fail fast”。

问题11.对于大型系统的秒杀,比如12306,同时进行的秒杀活动很多,如何分流?

答:垂直拆分

问题12、额外又想到一个问题。这套流程做成同步还是异步的?如果是同步的话,应该还存在会有响应反馈慢的情况。但如果是异步的话,如何控制能够将响应结果返回正确的请求方?

答:用户层面肯定是同步的(用户的http请求是夯住的),服务层面可以同步可以异步。

问题13、秒杀群提问:减库存是在那个阶段减呢?如果是下单锁库存的话,大量恶意用户下单锁库存而不支付如何处理呢?

答:数据库层面写请求量很低,还好,下单不支付,等时间过完再“回仓”,之前提过了。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

架构师之道 秒杀系统优化思路 的相关文章

  • 浅谈tidb事务与MySQL事务之间的区别

    MySQL是我们日常生活中常见的数据库 他的innodb存储引擎尤为常见 在事务方面使用的是扁平事务 即要么都执行 要么都回滚 而tidb数据库则使用的是分布式事务 两者都能保证数据的高一致性 但是在实现方式上是不一样的 我们先来看看MyS
  • 从事Java三年多,去应聘16k最后没被录用,细节如下……

    前言 今天小编和大家分享一位以前面试的一位应聘者 工作4年26岁 统招本科 以下就是他的简历和面试情况 基本情况 专业技能 1 熟悉Sping了解SpringMVC SpringBoot Mybatis等框架 了解SpringCloud微服
  • 电子企业MES管理系统架构分析

    随着电子制造行业的快速发展 MES生产管理系统的应用越来越普遍 许多制造企业购买或自主研发了适合自己工厂的MES 旨在实现智能工厂 车间 的目标 作为智能制造的核心 MES管理系统解决方案在企业智能化转型升级中发挥着越来越重要的作用 然而
  • Key-Value存储系统简介

    Redis是一个Key Value存储系统 和Memcached类似 它支持存储的value类型相对更多 包括string 字符串 list 链表 set 集合 和zset 有序集合 这些数据类型都支持push pop add remove
  • 死锁算法:银行家算法和安全性算法

    死锁算法 银行家算法和安全性算法 借鉴了一些文章 自己总结了一下 银行家算法 首先 算法的核心在于 每次进程申请资源时 都会进行一次试探性分配 若成功 则真实分配 基本思想 在每个新进程进入系统时 他必须声明在运行过程中 可能需要的每种资源
  • NUMA模式

    NUMA模式 补充经常听师兄们提到一个词NUMA模式 NUMA架构产生的背景 早期的计算机中 内存控制器在北桥中 所有CPU对内存的访问都要通过北桥来完成 此时所有CPU访问内存都是 一致的 如下图所示 这样的架构称为UMA Uniform
  • 在Jenkins管道中添加Webhook

    你有没有尝试过在Jenkins中添加GitHub webhook 在这篇博客中 我将演示在您的管道中添加webhook的最简单方法 首先 什么是webhook webhook的概念很简单 webhook是一个HTTP回调 当通过HTTP P
  • MES管理系统在电子行业的作用和效益

    电子行业近年来发展很好 特别是MES管理系统对于生产的帮助 电子行业MES管理系统促进了行业的数字化转型 从而提高电子行业高效管理 使企业效益最大化 电子行业现状 1 产品 顶级企业只负责设计与销售 对于涉及制造的各级企业产品较多 并且产品
  • 软件结构化设计-架构真题(二十七)

    2019年 进程P有8个页面 页号分别为0 7 状态位等于1和0分别表示在内存和不在内部才能 假设系统给P分配4个存储块 如果进程P要访问页面6不在内存 那么应该淘汰号是多少 答案 页号2 解析 页号1 2 5 7在内部内存里 而2的被访问
  • mysql Heartbeat主主同步方案

    Heartbeat高可用Mysql主主同步方案 1 1 方案简介 本方案使用heartbeat mysql主主同步来实现mysql数据库的高可用 当服务器或者master的heartbeat宕掉以后会自动切换到backup上 服务器或者ma
  • 系统架构设计高级技能 · 系统质量属性与架构评估

    系列文章目录 系统架构设计高级技能 软件架构概念 架构风格 ABSD 架构复用 DSSA 一 系统架构设计师 系统架构设计高级技能 系统质量属性与架构评估 二 系统架构设计师 系统架构设计高级技能 软件可靠性分析与设计 三 系统架构设计师
  • 系统架构设计知识梳理--分布式架构

    CAP理论 C 一致性 一般指强一致性 A 可用性 常见指标TP999 P 分区容错性 其中一致性与可用性存在矛盾 需要开发者根据实际业务取舍 一致性解决方案 Raft算法 原理是将集群中所有服务归为三类角色 leader 领导者 foll
  • 系统架构设计师之网络安全-各个层次的网络安全保障

    系统架构设计师之网络安全 各个层次的网络安全保障
  • 初级PHP工程师对于进阶的思考

    突然想写篇博客记录下刚毕业这段时间的经历 主要是对于人生的下一阶段的思考和诸多事物触起的思考 一 人生的下一阶段 人生的意义从来不是为自己奋斗 生活的意义也从来不是奋斗 今年毕业 距离博文发表的现在约莫有2个月 毕业前的我是一个极度执着追求
  • 系统架构设计高级技能 · 通信系统架构设计理论与实践

    现在的一切都是为将来的梦想编织翅膀 让梦想在现实中展翅高飞 Now everything is for the future of dream weaving wings let the dream fly in reality 点击进入系
  • 软件质量属性

    质量特性 质量子特性 功能性 适宜性 准确性 互用性 依从性 安全性 可靠性 成熟型 容错性 可恢复性 可用性 可理解性 易学性 可操作性 效率 时间特性 资源特性 可维护性 可分析性 可修改性 稳定性 可测试性 可移植性 适应性 易安装性
  • 通用技术 关于线上监控的思考总结

    前言 近期和大佬们对规划 梳理新财年要做的事情 有非常重要的一项就是线上监控 对于线上监控 大家都最熟悉不过 凡是在生产环境上运行的系统 或多或少都会有监控 但是否有思考过哪些监控是有效的 监控的目的是什么 监控告警出来之后又是怎么的一轮操
  • 程序的链接

    程序的链接是一个非常实际的问题 他建立在很实际的问题之上 不从程序员的角度去思考问题 则是从软件的角度去思考如何复用错综复杂的代码 因为 这个问题的本质是我们没有给底层的硬件一个完整的可按顺序执行的程序 我们在前几章虽然讨论了指令流的问题
  • 系统架构设计师 8:系统质量属性与架构评估

    软件系统属性包括功能属性和质量属性 软件架构重点关注的是质量属性 为了精确 定量地表达系统的质量属性 通常会采用质量属性场景的方式进行描述 在确定软件系统架构 精确描述质量属性场景后 就需要对系统架构进行评估 软件系统架构评估是在对架构分析
  • Java架构师系统架构高可用维度分析

    目录 1 导语 2 可用性介绍 3 本地高可用 集群 分布式 4 本地高可用 数据逻辑保护 5 异地容灾 双活 两地三中心 6 异地容灾 DRP规划 BCP业务连续性 7 多活和妥协方案 8 高可用流程 9 总结 想学习架构师构建流程

随机推荐

  • 【学习笔记】mybatis-generator自动生成工具的使用教程 2021最新版

    一 什么是mybatis generator mybatis geneator是一款mybatis自动代码生成工具 可以通过配置 快速生成DAO POJO和xml等文件 二 如何在IDEA上使用mybatis generator 1 导入依
  • Redis Stream 数据结构实现原理真的很强

    1 是什么 Stream 是 Redis 5 0 版本专门为消息队列设计的数据类型 借鉴了 Kafka 的 Consume Group 设计思路 提供了消费组概念 同时提供了消息的持久化和主从复制机制 客户端可以访问任何时刻的数据 并且能记
  • dft转换与反转

    这次介绍下opencv中DFT的使用 对应的例程是 EXAMPLE dft 在图像处理领域 通过DFT可以将图像转换到频域 实现高通和低通滤波 还可以利用矩阵的卷积运算等同于其在频域的乘法运算从而优化算法降低运算量 即先将图像转换到频域 然
  • 容器化部署 Jib

    概念 Google Jib 容器化构建工具 Jib是google开源的Java容器化工具 可以直接构建 Java 应用的 Docker 和 OCI 镜像的类库 以 Maven 和 Gradle 插件形式提供 通过 Jib Java 开发者可
  • 【省带宽、压成本专题】从产品架构来看,PCDN如何节流50%

    过去几年 我们一直在视频省流量方面潜心钻研 取得不俗的成果 本次 省带宽 压成本 系列一共会推出六篇文章 从技术迭代 硬件更新等角度出发 向大家介绍节省CDN流量 降低视频播放成本的方法 第一篇 从产品架构来看 PCDN如何节流50 目前国
  • 华为OD机试 - 欢乐的周末(Java)

    题目描述 小华和小为是很要好的朋友 他们约定周末一起吃饭 通过手机交流 他们在地图上选择了多个聚餐地点 由于自然地形等原因 部分聚餐地点不可达 求小华和小为都能到达的聚餐地点有多少个 输入描述 第一行输入m和n m代表地图的长度 n代表地图
  • 哈佛商学院私人笔记:如何一天拥有48小时?

    你的身边有没有这样一群人 永远精力充沛 永远有用不完的时间 工作 社交 生活 兴趣什么都不落下 谁都知道这得益于他们对时间的高效利用 但具体的妙招是什么呢 刚来到学校 哈佛 的时候我就被告知 你们的第一年是故意设计成很紧张的时间表 以锻炼你
  • C 标准库 - 《stdarg.h》

    原文链接 https www runoob com cprogramming c standard library stdarg h html 简介 stdarg h 头文件定义了一个变量类型 va list 和三个宏 这三个宏可用于在参数
  • STM32——DS18B20温度传感器

    一 DS18B20介绍 一 DS18B20技术性能特征 1 独特的单总线接口方式 DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯 大大提高了系统的抗干扰性 2 测温范围 55 C 125 C 3 支
  • 串口服务器485转以太网

    串口服务器485转以太网可以将485等串口设备连接到网络中 让这些设备采集的数据发往网络 建立串口和网络的透明传输通道 实现设备联网 用户可以使用组态软件或者自己编写网络通信程序和设备通信 上海卓岚串口服务器可支持虚拟串口协议 使得您也可以
  • [编程入门]自定义函数之字符串拷贝

    题目要求 有一字符串 包含n个字符 写一函数 将此字符串中从第m个字符开始的全部字符复制成为另一个字符串 include
  • java判断字符串String是否为空

    java判断字符串String是否为空 1 判空的四个方法 2 区别 和equals null和 3 推荐使用 1 判空的四个方法 1 str null length就是取得字符串的长度 2 str length 0 3 equals st
  • 亚马逊S3Client实现上传下载功能

    首先引入依赖
  • Vue3通透教程【二】更高效的构建工具—Vite

    文章目录 写在前面 webpack Vite是什么 使用Vite创建项目 写在最后 写在前面 专栏介绍 凉哥作为 Vue 的忠实 粉丝输出过大量的 Vue 文章 应粉丝要求开始更新 Vue3 的相关技术文章 Vue 框架目前的地位大家应该都
  • 2019/10/3 CSP-S 模拟测

    T1 Permut 题意 求 1 n 的排列中逆序对数量为 k 的排列的个数 SOL 排除法我们知道一定不是 O n 的算法 考虑 dp 现在已经有 n 1 的答案了 考虑新加入一个数产生多少新的逆序对 设 dp i j 表示 1 i 的排
  • flea-cache使用之Redis集群模式接入

    Redis集群模式接入 1 参考 2 依赖 3 基础接入 3 1 定义Flea缓存接口 3 2 定义抽象Flea缓存类 3 3 定义Redis客户端接口类 3 4 定义集群模式Redis客户端实现类 3 5 定义Redis集群连接池 3 6
  • DataV:可能是我用过最可怕的数据可视化神器

    每年的双十一 天猫都会在剁手狂欢节中直播战绩 除了可怕的数字之外 不知道大家有没有留意到这些同样可怕的 数据可视化大屏 2015双十一大屏 2016双十一大屏 所谓大屏 顾名思义就是一个 很大的屏 一般应用在交易大厅 展览中心 管控中心 老
  • 关于java中IO的个人理解

    一 什么是java的I O I O中的i为input即输入的意思 O为output输出的意思 所以io为java中数据的输入和输出 这里的数据即包括网络上的数据 socket 也包括本地的文件数据 IO使用流的概念来进行数据的输入和输出也就
  • 希沃展台如何使用_【希沃视频展台--让课堂展示从未如此轻松!】PjTime.COM 综合导购 希沃...

    无论是作业试卷的讲解 还是实验过程展示 课堂展示对于课堂效率的提升始终起着重要的作用 然而目前市场上还是充斥着不少操作复杂 清晰度十分尴尬的展台产品 影响着老师的课堂效果 为此我们特意打造了希沃 7系列视频展台 一款简单又强大的视频展台 希
  • 架构师之道 秒杀系统优化思路

    本文曾在 架构师之路 上发布过 近期支援Qcon AS大会 在微信群里分享了该话题 故对原文进行重新整理与发布 一 秒杀业务为什么难做 1 im系统 例如qq或者微博 每个人都读自己的数据 好友列表 群列表 个人信息 2 微博系统 每个人读