06 | 秒杀系统“减库存”设计的核心逻辑
该思维导图由 AI 生成,仅供参考
减库存有哪几种方式
- 深入了解
- 翻译
- 解释
- 总结
文章总结:秒杀系统中的减库存设计是核心逻辑之一,本文介绍了减库存的核心问题和几种方式,包括下单减库存、付款减库存和预扣库存,并分析了它们可能存在的问题。针对大型秒杀活动,建议采用“下单减库存”方式,因为成功下单后不付款的情况较少,且逻辑简单性能优势明显。在数据一致性上,需要保证库存数据不能为负数,可以通过事务、设置数据库字段为无符号整数或使用CASE WHEN判断语句来实现。文章强调了在实际应用中需要结合安全和反作弊措施来解决恶意下单和库存超卖等问题。此外,文章还探讨了秒杀场景下减库存的极致优化思路,包括在缓存中减库存和在数据库中减库存的方式。针对数据库并发锁的问题,提出了应用层和数据库层做排队的解决办法,并介绍了阿里的数据库团队开发的针对MySQL的InnoDB层上的补丁程序,以及数据更新操作的优化方法。总结来说,本文围绕商品减库存的场景,介绍了减库存的实现方案、存在的问题和缓解办法,以及在秒杀场景下的极致优化思路,为读者提供了深入的技术内容。
《如何设计一个秒杀系统》
全部留言(108)
- 最新
- 精选
- 周龙亭下单和扣库存两个操作的事务性是怎么做的?
作者回复: 可以分两步来做,先创建订单但是先不生效,然后减库存,如果减库存成功后再生效订单,否则订单不生效
2018-10-07932 - 刘小刘老师,我觉得你讲的不太明白,你并没有说实际情况下同步是怎样解决并发的,没看到您给的方案,只看到您在评论回复里否定了队列异步处理的方式
作者回复: 解决的办法就是尽可能避免产生锁,比如根据商品ID进行分库分表设计;再有就是减少锁的粒度例如阿里对MySQL做了定制优化,可以提升MySQL的并发度
2018-12-21220 - Geek_c19c96我们的库存都放在redis里面,读和减库存都在redis里面操作,redis会定时将库存放到mysql中做备份,
作者回复: 😉
2018-10-161011 - 公号-技术夜未眠许老师好,我有一个想法,只是没有在实践中这样做过,请指教: 能否借用"数据库水平拆分"的思想? 具体思路如下: 库存在数据库的表中就只有一行数据,上面的方案都是对这一条记录进行频繁更新,是非常"热"的热点数据。我们能否将该行数据拆分到不同的数据库中,这些数据库的库存记录之和就是原始库存数量。这样能否会降低数据库的写压力,提高吞吐量?
作者回复: 实际上,商品都是进行分库分表的,例如根据商品id进行水平拆分 分库分表就是提高吞吐量
2018-10-06411 - 我是李香兰小朋友“按照商品维度设置队列顺序执行”这句话是什么意思?可以举例说明一下吗?谢谢老师
作者回复: “按照商品维度设置队列顺序执行”的意思就是,为了防止同一个商品对数据库的操作占用太多的数据库资源,所以采用队列的方式,让其他商品也有公平的机会得到数据的响应,例如如果秒杀的时候,秒杀商品肯定占用大量的请求,数据库的连接池有可能都被秒杀商品占用了,如果不做队列的话,那么其他商品就得不到数据库执行机会了。加入我们分10个队列,那么秒杀商品就会落在这10个队列中的一个,那么最多也就占用机器10分之一的资源。
2018-10-1310 - Coder4这种无只能在串行隔离级别才能用吧,不然肯定超售。。。UPDATE item SET inventory = CASE WHEN inventory >= xxx THEN inventory-xxx ELSE inventory END
作者回复: 数据库层不都是串行操作吗😊
2018-10-061710 - 永光老师,你好, 你提到秒杀商品减库存直接放到缓存系统中实现,也就是直接在缓存中减库存或者在一个带有持久化功能的缓存系统(如 Redis)中完成。这种实现并发读写怎样保持数据一致?以及是不是要用分布式缓存?
作者回复: 前面有个同学的类似的问题回答过,可以看一下
2018-10-0610 - shawn个人做法, 针对确定库存,提前下好单,下单人留空,订单短时间内失效 订单id压入Redis队列, 请求来到,订单队列lpop,队空则返回失败, pop出来的订单补充下单人为当前用户, 如果订单过期失效则再次下同一商品的空单存入队列 这个设计可以考虑单个Redis不够用的时候将队列分组,利用轮转或时间戳hash将请求分配到不同队列, 想问下老师,这个和扣数字库存相比,会不会有更好的并发性能呢?
作者回复: 说实话,没看出来哪里性能会更好😄 不过提前下单的思路还比较新颖,你的思路我理解,但是这样就把一个事情分两次来做,会增加了复杂度,有可能导致得不偿失
2018-10-1469 - 一笑奈何老师,问下单机mysql 1s内能抗大约多大的QPS? 大约。
作者回复: 我印象中单实例一般能抗7-8k左右
2018-10-0629 - 大麦秒杀是短时间大量请求,使用下单即锁库存方式,可以通过一个 redis 队列记录下单,一个redis key 记录数量 num,超出的库存下单失败,这样大量请求在 redis 层即可被处理。 通过 num 与库存的判断来解决无效订单。 下单端通过队列异步消费下单。 对于前端,用户下单成功,即进入redis 队列的,响应给前端可以轮询。 没有的,直接提示抢购失败。
作者回复: 异步下单的方式,也是一个思路,例如在一些场景下其实已经在使用,例如一些支付场景中,付了款以后,前端页面中会有一个转圈,等个几秒钟再告诉你结果。 这种方式我个人觉得对用户不太友好,就是要让用户等个几秒钟,而不是像同步的方式能及时得到反馈结果
2018-10-1237