mysql 高并发扣除库存_互联网如何高并发扣减库存

本文使用的库存数量模型

本文为了描述方便,我们使用简化的库存数量模型,真实使用实际的库存数量项可根据实际需要设计。

库存数量表-stockNum

字段名英文名字段类型

商品标识skuId长整型

库存数量num整数

传统通过数据库保证不超卖

通过Sql里判断剩余的库存数够用,多个并发执行update语句只有一个能执行成功。

Update stockNum set num=num-下单数量 where skuId=商品ID and num-下单数量>0

本方法并不是本文重点,使用数据库做数量扣减,面临高并发就没有办法进行抗量,我们接下来设计一种使用Redis缓存做库存扣减的方案。

PS:分库分表并不能根本解决库存扣减的高并发,因为分库分表是按商品,促销的时候高并发都是针对少量商品的,甚至是一个商品,最终并发流量会打向少数表,分库分表会起不到作用,只能去提升单分片的并发能力。

Redis做扣减的原理

扣减库存其实包含两部分,第一部分超卖校验,第二部分最终扣减掉库存;在传统数据库扣减中,两部是一起完成的,同时完成了超卖校验(where中的判断)和扣减(update数量);如果我们想解决这两部分,就需要把两个问题分开解决:

第一关解决超卖检验:我们可以把数据放入Redis中,每次扣减库存,都对Redis中的数据进行incryby扣减,如果返回的数量大于0,说明库存够,因为Redis是单线程,可以信任返回结果。第一关是Redis,可以抗高并发,性能Ok。超卖校验通过后,进入第二关。

第二关解决库存扣减:经过第一关后,第二关不需要再判断数量是否足够,只需要傻瓜扣减库存就行,对数据库执行如下语句:

Update stockNum set num=num-下单数量 where skuId=商品ID

疑问来了,此处因为数据库是按商品分库分表,并发量又没有减少,问题不是没有解决吗?是的,还需要引入一个重量级武器,任务库,我们并不直接在业务库上执行上面的扣减语句,我们只在任务库记录这个扣减任务,再异步进行扣减就可以。任务库使用订单号或其他可以散列开的字段进行分库分表,这样针对同一个商品的不同订单会散列在任务库的不同库存,虽然还是数据库抗量,但已经消除了数据库热点。

整体架构如下:

faf008c9f758c50275aefcff569cfce6.png

数量校验和数据持久化分开了,Redis缓存负责校验数量,异步任务负责数据持久化。

在后续文章中,我会对任务库的设计进行介绍,任务库不仅仅可以做数据的最终一致性,也可以作为状态机引擎支撑起状态机,服务于状态机业务。

本文地址:https://blog.csdn.net/qrycf/article/details/110495295

希望与广大网友互动??

点此进行留言吧!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值