高频面试题:秒杀场景设计

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 秒杀这个话题到现在来说已经是一个老生常谈的话题了,不过因为又临近一年一度的双11,而且发现前段时间无论是阿里还是腾讯一些大厂其实还是在频繁的问到这个场景题,所以还是准备拿出来说说。

秒杀这个话题到现在来说已经是一个老生常谈的话题了,不过因为又临近一年一度的双11,而且发现前段时间无论是阿里还是腾讯一些大厂其实还是在频繁的问到这个场景题,所以还是准备拿出来说说。

秒杀从规模上来说可以分为大秒和小秒。大秒指的是比如双11这种特定的节日,商品规模超大、价格超低、流量超大的这种类型活动,小秒一般指的是商家自己配置的一些时段类型的活动,由商家自己指定时间上架。从形式来说还可以分为单时段秒杀和多时段秒杀。但是在这个场景里,我们一般就是指的单时段大型秒杀。

秒杀设计要面对的压力和难度有几点:

  1. 怎么保证超高的流量和并发下系统的稳定性?如果峰值的QPS达到几十万,面对巨大的流量的压力系统怎么设计保证不被打崩?
  2. 怎么保证数据最终一致性?比如库存不能超卖,超卖了那亏本的要么就是商家要么就是平台,用户反正不背这个锅,超卖了就今年325预订。

当然,涉及到这种大型的活动,还需要考虑到数据统计分析,总不能活动做完了,效果不知道怎么样。

系统架构

假设今年的双11预估峰值QPS将会有50万(我随便扯的),而根据我们平时的经验单机8C8G的机器可以达到1000左右的QPS,那么从理论上来说我们只要500台机器就可以抗住了,就有钱任性不行?这么设计的话只能出门右转不送了。

流量过滤

本质上,参与秒杀的用户很多,但是商品的数量是有限的,真正能抢到的用户并不多,那么第一步就是要过滤掉大部分无效的流量。

  1. 活动开始前前端页面的Button置灰,防止活动未开始无效的点击产生流量
  2. 前端添加验证码或者答题,防止瞬间产生超高的流量,可以很好的起到错峰的效果,现在的验证码花样繁多,题库有的还要做个小学题,而且题库更新频繁,想暴力破解怕是很难。当然我知道的还有一种人工打码的方式,不过这个也是需要时间的,不像机器无限刷你的接口。
  3. 活动校验,既然是活动,那么活动的参与用户,参加条件,用户白名单之类的要首先做一层校验拦截,还有其他的比如用户终端、IP地址、参与活动次数、黑名单用户的校验。比如活动主要针对APP端的用户校验,那么根据参数其他端的用户将被拦截,针对IP、mac地址、设备ID和用户ID可以对用户参与活动的次数做校验,黑名单根据平时的活动经验拦截掉一部分羊毛党等异常用户。
  4. 非法请求拦截,做了以上拦截如果还有用户能绕过限制,那不得不说太牛X了。比如双11零点开始还做了答题限制,那么正常人怎么也需要1秒的时间来答题吧,就算单身30年手速我想也不能超过0.5秒了,那么针对刚好0点或者在0.5秒以内的请求就可以完全拦截掉。
  5. 限流,假设秒杀10000件商品,我们有10台服务器,单机的QPS在1000,那么理论上1秒就可以抢完,针对微服务就可以做限流配置,避免后续无效的流量打到数据库造成不必要的压力。针对限流还有另外一种栅栏方式限流,这是一种纯靠运气的限流方式,就是在系统约定的请求开始的时间内随机偏移一段时间,针对每个请求的偏移量不同,如果在偏移时间之内就会被拦截,反之通过。

b7009b49ab5f14315916d17367bb9840.jpg

性能优化

做完无效流量的过滤,那么可能你的无效请求已经过滤掉了90%,剩下的有效流量会大大的降低系统的压力。之后就是需要针对系统的性能做出优化了。

  1. 页面静态化,参与秒杀活动的商品一般都是已知的,可以针对活动页面做静态化处理,缓存到CDN。假设我们一个页面300K大小,1千万用户的流量是多少?这些请求要请求后端服务器、数据库,压力可想而知,缓存到CDN用户请求不经过服务器,大大减小了服务器的压力。
  2. 活动预热,针对活动的活动库存可以独立出来,不和普通的商品库存共享服务,活动库存活动开始前提前加载到redis,查询全部走缓存,最后扣减库存再视情况而定。
  3. 独立部署,资源充足的情况下可以考虑针对秒杀活动单独部署一套环境,这套环境中可以剥离一些可能无用的逻辑,比如不用考虑使用优惠券、红包、下单后赠送积分的一些场景,或者这些场景可以活动结束后异步的统一发放。这只是一个举例,实际上单独针对秒杀活动的话你肯定有很多无用的业务代码是可以剥离的,这样可以提高不少性能。

经过这两步之后,最终我们的流量应该是呈漏斗状。

3207e0618bdf7c9331da4e86f1a44984.jpg

超卖

秒杀除开高并发高流量下的服务稳定性之外,剩下的核心大概就是怎么保证库存不超卖了,也可以说要保证的是最终一致性。一般来说,针对下单和库存有两种方式:

  1. 下单即扣库存,这是最常规的大部分的做法。但是可能在活动中会碰到第二点说到的情况。
  2. 支付完成扣库存,这种设计我碰到过就是酒店行业,廉价房放出来之后被黄牛下单抢占库存导致正常用户无法下单,然后黄牛可以用稍高的价格再售卖给用户从中牟利,所以会有在一些活动的时候采取支付成功后才占用库存的做法。不过这种方式实现起起来比较复杂,可能造成大量的无效订单,在秒杀的场景中不太适用

针对秒杀建议选择下单扣库存的方式,实现相对简单而且是常规做法。

方案

738a0a4e8e11839b4a964ff3aabe4c9a.jpg

  1. 首先查询redis缓存库存是否充足
  2. 先扣库存再落订单数据,可以防止订单生成了没有库存的超卖问题
  3. 扣库存的时候先扣数据库库存,再扣减redis库存,保证在同一个事务里,无论两者哪一个发生了异常都会回滚。有一个问题是可能redis扣成功了由于网络问题返回失败,事务回滚,导致数据库和缓存不一致,这样实际少卖了,可以放到下轮秒杀去。

这种做法能一定程度上解决问题,但是也有可能会有其他问题。比如当大量请求落在同一条库存记录上去做update时,行锁导致大量的锁竞争会使得数据库的tps急剧下降,性能无法满足要求。

另外一种做法就是排队,在服务层进行排队,针对同一个商品ID的也就是数据库是一条库存记录的做一个内存队列,串行化去扣减库存,可以一定程度上缓解数据库的并发压力。

质量保障

为了保证系统的稳定性,防止你的系统被秒杀,一些质量监控就不得不做。

  1. 熔断限流降级,老生常谈,根据压测情况进行限流,可以使用sentinel或者hystrix。另外前端后端都该有降级开关。
  2. 监控,该上的都上,QPS监控、容器监控、CPU、缓存、IO监控等等。
  3. 演练,大型秒杀事前演练少不了,不能冒冒失失的就上了吧。
  4. 核对、预案,事后库存订单 金额、数量核对,是否发生超卖了?金额是否正常?都是必须的。预案可以在紧急情况下进行降级。

数据统计

活动做完了,数据该怎么统计?

  1. 前端埋点
  2. 数据大盘,通过后台服务的打点配合监控系统可以通过大盘直观的看到一些活动的监控和数据
  3. 离线数据分析,事后活动的数据可以同步到离线数仓做进一步的分析统计

总结

总的来说,面对巨量的流量我们的方式就是首先通过各种条件先筛选掉无效流量,进行流量错峰,然后再对现有的系统性能做出优化,比如页面静态化,库存商品预热,也可以通过独立部署的方式和其他的环境做隔离,最后还要解决高并发下缓存一致性、库存不能超卖的问题,防止大量的并发打爆你的数据库。

一个完整的活动从前端到后端是一个完整的链路,中间有事前的演练工作,事后的数据分析等都是必不可少的环节。



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
9月前
|
存储 SQL 数据库
面试官:索引失效场景有哪些?
以下是内容的摘要: 本文列举了可能导致数据库索引失效的16种情况:全表扫描、索引列使用计算或函数、LIKE查询条件不匹配、未遵循联合索引最左前缀原则、索引列参与排序无筛选、隐式类型转换、OR条件连接索引、IN子句大量值、NOT操作、数据分布不均的JOIN、数据过于分散的查询、大结果集、临时表或派生表操作、索引维护不及时以及不等于比较和IS NOT NULL条件。这些情况都可能使查询优化器放弃使用索引,影响查询性能。
329 1
|
9月前
|
存储 缓存 监控
美团面试:说说OOM三大场景和解决方案? (绝对史上最全)
小伙伴们,有没有遇到过程序突然崩溃,然后抛出一个OutOfMemoryError的异常?这就是我们俗称的OOM,也就是内存溢出 本文来带大家学习Java OOM的三大经典场景以及解决方案,保证让你有所收获!
2623 0
美团面试:说说OOM三大场景和解决方案? (绝对史上最全)
|
缓存 安全 Java
【面试题精讲】反射的应用场景
【面试题精讲】反射的应用场景
【面试题精讲】JVM-类加载器-应用场景
【面试题精讲】JVM-类加载器-应用场景
|
18天前
|
消息中间件 存储 Java
招行面试:10Wqps场景,RocketMQ 顺序消费 的性能 如何提升 ?
45岁资深架构师尼恩在其读者群中分享了关于如何提升RocketMQ顺序消费性能的高并发面试题解析。面对10W QPS的高并发场景,尼恩详细讲解了RocketMQ的调优策略,包括专用方案如增加ConsumeQueue数量、优化Topic设计等,以及通用方案如硬件配置(CPU、内存、磁盘、网络)、操作系统调优、Broker配置调整、客户端配置优化、JVM调优和监控与日志分析等方面。通过系统化的梳理,帮助读者在面试中充分展示技术实力,获得面试官的认可。相关真题及答案将收录于《尼恩Java面试宝典PDF》V175版本中,助力求职者提高架构、设计和开发水平。
招行面试:10Wqps场景,RocketMQ 顺序消费 的性能 如何提升 ?
|
6月前
|
JavaScript
【Vue面试题十四】、说说你对vue的mixin的理解,有什么应用场景?
这篇文章详细介绍了Vue中`mixin`的概念、应用场景和源码分析,解释了`mixin`如何用于代码复用、功能模块化,并通过实际代码示例展示了在Vue组件中局部混入和全局混入的使用方式。
【Vue面试题十四】、说说你对vue的mixin的理解,有什么应用场景?
|
6月前
|
并行计算 数据挖掘 大数据
[go 面试] 并行与并发的区别及应用场景解析
[go 面试] 并行与并发的区别及应用场景解析
|
3月前
|
架构师 数据库
大厂面试高频:数据库乐观锁的实现原理、以及应用场景
数据库乐观锁是必知必会的技术栈,也是大厂面试高频,十分重要,本文解析数据库乐观锁。关注【mikechen的互联网架构】,10年+BAT架构经验分享。
大厂面试高频:数据库乐观锁的实现原理、以及应用场景
|
2月前
|
Java 关系型数据库 数据库
京东面试:聊聊Spring事务?Spring事务的10种失效场景?加入型传播和嵌套型传播有什么区别?
45岁老架构师尼恩分享了Spring事务的核心知识点,包括事务的两种管理方式(编程式和声明式)、@Transactional注解的五大属性(transactionManager、propagation、isolation、timeout、readOnly、rollbackFor)、事务的七种传播行为、事务隔离级别及其与数据库隔离级别的关系,以及Spring事务的10种失效场景。尼恩还强调了面试中如何给出高质量答案,推荐阅读《尼恩Java面试宝典PDF》以提升面试表现。更多技术资料可在公众号【技术自由圈】获取。
|
6月前
|
JavaScript 前端开发
【Vue面试题二十一】、Vue中的过滤器了解吗?过滤器的应用场景有哪些?
这篇文章介绍了Vue中的过滤器,包括过滤器的定义、使用方式、串联使用以及在Vue 3中的废弃情况,并探讨了过滤器在文本格式化、单位转换等场景下的应用,同时分析了过滤器在Vue模板编译阶段的工作原理。
【Vue面试题二十一】、Vue中的过滤器了解吗?过滤器的应用场景有哪些?

热门文章

最新文章