广告
返回顶部
首页 > 资讯 > 精选 >Redis如何解决库存超卖问题
  • 874
分享到

Redis如何解决库存超卖问题

2023-06-06 17:06:37 874人浏览 八月长安
摘要

这篇文章主要介绍“Redis如何解决库存超卖问题”,在日常操作中,相信很多人在Redis如何解决库存超卖问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Redis如何解决库存超卖问题”的疑惑有所帮助!接下来

这篇文章主要介绍“Redis如何解决库存超卖问题”,在日常操作中,相信很多人在Redis如何解决库存超卖问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Redis如何解决库存超卖问题”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

商品和订单服务间使用MQ

商品服务的库存变化时,通过 MQ 通知订单服务库存变化。

原始的同步流程

  1. 查询商品信息 (调用商品服务)

  2. 计算总价(生成订单详情)

  3. 商品服务扣库存(调用商品服务)

  4. 订单入库( 生成订单)

// 原始的MySQL同步流程// 判断此代金券是否加入抢购SeckillVouchers seckillVouchers = seckillVouchersMapper.selectVoucher(voucherId);AssertUtil.isTrue(seckillVouchers == null, "该代金券并未有抢购活动");// 判断是否有效AssertUtil.isTrue(seckillVouchers.getIsValid() == 0, "该活动已结束");// 插入数据库seckillVouchersMapper.save(seckillVouchers);

在订单生成时直接扣库存,这是最原始的扣库存方案,比较简单,但存在问题

  • 可能导致很多订单把产品库存扣除而未支付,这就需要有一个后台脚本,将一段时间内没有支付的订单的库存释放,把订单取消即时扣库存,并发

  • 3步商品服务,操作商品服务的 db,2、4步订单服务,操作订单服务的 db。

避免访问不同服务的 db,原则上同一服务只能操作自身服务的 db。

MQ异步化

首先考虑只将第4步异步。

分析

2,4都是操作db,第4步不再等待,1、2、3成功后立即反馈给用户。

之后通过消息通知服务异步下单,若第4步异步下单失败,重试操作,试图重新生成订单,MQ的消息也可回溯。


Redis如何解决库存超卖问题

订单创建完成后,处于排队状态,然后服务发布一个事件Order Created消息队列中。
即订单服务向外界发送消息:我创建了一个订单,由MQ 转发给订阅该消息的服务


Redis如何解决库存超卖问题

如果商品服务收到创建订单消息之后执行扣库存操作。注意,这里可能因为某些不可抗因素导致扣库存失败,无论成功与否,商品服务都会发送一个扣库存消息到 MQ,消息内容即扣库存的结果。
订单服务会订阅扣库存的结果,接收到该消息后:

  • 如果扣库存成功,将订单的状态改为已确认,即下单成功

  • 如果扣库存失败,将订单的状态改为已取消,即下单失败

欲实现上述模型要求,需可靠的消息投递。服务发出的消息,一定会被MQ收到。

  • 用户体验的变化,前端配合排队中等界面。

商品/订单服务都变成异步化,适合秒杀类场景,当流量不大时,并不太适合。

异步设计

  1. 库存在Redis中保存

  2. 收到请求Redis判断是否库存充足 ,减掉Redis中库存

  3. 订单服务创建订单写入数据库,并发送消息

当订单支付成功后,会有一个出库过程,既然有这个过程,就有可能出库失败。
库存有两部分:

  1. 当客服新增5个库存,则缓存redis和数据库mysql层都需增加5个库存,使用分布式事务的最终一致性来满足:库存要么全加,要么全不加。

  2. 当订单生成时,需要扣除库存,先扣redis库存,如果扣除成功,则生成订单进行支付,这个过程不扣除mysql库存。

  3. 当redis库存扣完,该产品就无法下单了,下单就会失败,就把外层的给挡住了。

  4. 在第2步扣除redis库存成功后,生成订单,进行支付,支付成功,返回我的订单中心, 会发现有一个出库过程。

  5. 出库过程一个MQ异步解耦的任务队列,这个过程是扣除mysql库存:

  • 如果扣mysql库存成功,出库成功,完成下订单整个流程,进入发货状态

  • 如果扣mysql库存失败,出库失败,进行一系列的操作

  1. 订单状态改成取消

  2. 返还redis库存

  3. 退款

redis库存和mysql库存

支付前是预扣,是扣redis库存,是定库存的过程
支付后是真正扣,扣mysql库存,保证库存最终一致

但是,在极端情况下会存在数据不一致

  • 如果redis库存 = mysql库存,不会有问题

  • 如果redis库存 < mysql库存,不会有超卖问题,但会存在实际有库存,但是没有卖的情况

  • 如果redis库存 > mysql库存,就会超卖,超卖的订单,在出库的过程中会失败

这样总体不会出问题,mysql数据库层,保证库存最终不会出问题。

问题

数据库库存和redis库存不一致,如何检测?

如果检测出来不一致,如何同步

没有想出来好的方案
比较暴力的方式,就是找一个低峰期,譬如凌晨1点,周期性强行覆盖。 但是极端情况下还是会存在同步后不准确,譬如在同步的过程中,刚好有一个订单在支付,这个订单支付成功后,出库的过程中,扣除了mysql的库存,但是没有扣除redis的库存

这个就是数据库同步缓存的更新机制方面的问题
属于一致性的逻辑设计的问题
缓存数 = 数据库库存数 - 待扣数
当然这里面也还有其它的方案,以及考虑到一致性的要求高低,可以使用简单或复杂的方案
就看系统复杂度了,越是大系统就要拆得越细
比如待扣数又可以放到一个队列里面,或者缓存里面,同时有计数,直接读计数就行
比如放到monGo,已支付待出库的数量,一般也不会很大,count一下,也不会损失多少
所以一般系统都不能完全保障数据链不出错,但一定要有补偿,就是出错了可以纠错
要保障不出错的代价显然太大
同步是有一套刷新机制,可以定时,也可以通过MQ,或者监控不一至同步等等。。。
也叫做保障缓存数据的新鲜度
一般不会太长时间,半小时,几分钟都有可能,不同场景需求不一样

12306

买火车票的12306,晚上的时间都不能买票,这个时间估计是在同步库存,将数据库库存同步到redis库存中, 但是买火车票之类,在订单生成前,必须扣除实际库存,也就是要扣除mysql的库存,

因为买火车票和购物不一样,购物可以付款后出库,但是买票这种,支付前就必须出库,因此,要将出库过程提前, 只有出库成功,才能生成订单,同样要引入redis库存

先扣缓存中的库存,扣除成功后,然后才可以去扣mysql中的库存。

如果扣除缓存中的库存失败,就会挡在外面,返回库存不足,这些请求不会穿刺到mysql中,挡住了大多数的请求压力。

redis库存会和mysql库存不一致,极端情况下是肯定有的,需要进行库存同步

  • 当缓存库存比数据库库存多,那么就会出现,查询有票,但是就无法下单,下单的时候就说库存不足,这个情况下,就会造成数据库压力过大,不过12306应该有其他手段来规避这个问题,不过,我确实遇到过,查询的时候有票,但是无法下单的情况。

  • 当缓存库存比数据库缓存少,那么不会出问题,只会出现有票,但是没有出售的情况,等完成库存同步一下, 明天又准确了。

到此,关于“Redis如何解决库存超卖问题”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: Redis如何解决库存超卖问题

本文链接: https://www.lsjlt.com/news/248083.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Redis如何解决库存超卖问题
    这篇文章主要介绍“Redis如何解决库存超卖问题”,在日常操作中,相信很多人在Redis如何解决库存超卖问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Redis如何解决库存超卖问题”的疑惑有所帮助!接下来...
    99+
    2023-06-06
  • Go+Lua解决Redis秒杀中库存与超卖问题
    目录0、简介1、简单版2、解决超卖3、解决库存问题Lua0、简介 Go语言连接go-Redis进行数据库的连接,如果你对这部分尚不了解,建议你先学习这部分知识。另外,本秒杀主要解决两个问题,第一个就是超卖问题,另一个就是...
    99+
    2023-03-01
    GoLuaRedis秒杀 GoLuaRedis库存与超卖
  • 解决redis秒杀超卖的问题
    小编给大家分享一下解决redis秒杀超卖的问题,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!首先,生成库存的计数量 public function kucun() { ...
    99+
    2022-10-18
  • redis商品超卖问题怎么解决
    Redis商品超卖问题是指在高并发情况下,商品库存被多次减少导致出现负库存的情况。解决Redis商品超卖问题可以使用以下几种方法: ...
    99+
    2023-10-21
    redis
  • Redis中秒杀场景下超时与超卖问题如何解决
    这篇文章主要介绍“Redis中秒杀场景下超时与超卖问题如何解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Redis中秒杀场景下超时与超卖问题如何解决”文章能帮助大家解决问题。超时1.redis连...
    99+
    2023-06-30
  • 怎么使用Go和Lua解决Redis秒杀中库存与超卖问题
    这篇文章主要介绍“怎么使用Go和Lua解决Redis秒杀中库存与超卖问题”,在日常操作中,相信很多人在怎么使用Go和Lua解决Redis秒杀中库存与超卖问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么使...
    99+
    2023-07-05
  • Redis分布式锁解决秒杀超卖问题
    目录分布式锁应用场景单体锁的分类分布式锁核心逻辑分布式锁实现的问题——死锁和解决Redis解决删除别人锁的问题分布式锁应用场景 秒杀环境下:订单服务从库存中心拿到库存数,如果库存总数大于0,则进...
    99+
    2022-07-13
    Redis秒杀超卖 Redis分布式锁
  • 如何解决Redis高并发防止秒杀超卖的问题
    这篇文章主要介绍了如何解决Redis高并发防止秒杀超卖的问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1:解决思路将活动写入 redis 中,通过 redis 自减指令扣...
    99+
    2023-06-25
  • PHP高并发之怎么解决商品库存超卖问题
    这篇文章主要介绍“PHP高并发之怎么解决商品库存超卖问题”,在日常操作中,相信很多人在PHP高并发之怎么解决商品库存超卖问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PHP高并发之怎么解决商品库存超卖问题...
    99+
    2023-06-29
  • Redis中秒杀场景下超时与超卖问题的解决方案
    目录超时1.redis连接超时原因2.解决方法超卖1.秒杀超卖现象2.解决方案(1)利用乐观锁淘汰用户,解决超卖问题(2)、使用reids的 watch + multi + setn...
    99+
    2022-11-13
  • Redis实现库存扣减的解决方案防止商品超卖
    目录Redis 如何实现库存扣减操作?如何防止商品被超卖?解决方案1. 使用mysql数据库2. 还是使用数据库3. 将库存放到redis使用redis的incrby特性来扣减库存。...
    99+
    2022-11-13
  • redis使用Lua脚本解决多线程下的超卖问题及原因解析
    目录一.多线程下引起的超卖问题呈现二.使用Lua脚本解决多线程下超卖的问题以及为什么三.为什么使用Lua脚本就能解决多线程下的超卖问题呢?一.多线程下引起的超卖问题呈现 1.1.我先...
    99+
    2023-05-19
    redis多线程超卖 lua脚本解决超卖问题
  • 怎么解决redis连接超时问题
    这篇文章给大家分享的是有关怎么解决redis连接超时问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。问题描述:redis连接超时,然后定位到redis配置文件目录被删除,接着尝...
    99+
    2022-10-18
  • Spring Boot如何解决Redis缓存+MySQL批量入库问题
    这篇文章给大家分享的是有关Spring Boot如何解决Redis缓存+MySQL批量入库问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。架构设计架构图:时序图记录基础数据MySQL表结构CREATE...
    99+
    2023-06-29
  • redis缓存和数据库一致性问题如何解决
    在使用Redis缓存时,常常会遇到与数据库一致性的问题。当数据发生变更时,需要保证Redis缓存与数据库的数据保持一致。以下是几种常...
    99+
    2023-08-24
    redis
  • 如何解决Redis缓存异常的问题
    这篇文章将为大家详细讲解有关如何解决Redis缓存异常的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。缓存雪崩缓存雪崩是指缓存同一时间大面积的失效,所以,后面的请求都...
    99+
    2022-10-19
  • Redis缓存问题怎么解决
    这篇文章主要讲解了“Redis缓存问题怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Redis缓存问题怎么解决”吧!LevelDB 来了!它是 Go...
    99+
    2022-10-19
  • session超时问题如何解决
    要解决会话超时问题,可以考虑以下几种方法:1. 增加会话超时时间:可以调整系统设置,延长会话超时时间,以允许用户有更长时间进行操作。...
    99+
    2023-09-21
    session
  • Redis解决跨域存取Session问题
    目录前言一、遇到的情况二、解决问题2.1 配置yml文件2.2 启动Redis2.3 代码编写三、效果演示总结前言 vue3+SpringBoot做项目时,由于vue前端项目是在8080端口运行,而后端项目是在8081端...
    99+
    2023-04-12
    Redis跨域存取Session Redis 存取Session
  • 详解redis缓存与数据库一致性问题解决
    数据库与缓存读写模式策略 写完数据库后是否需要马上更新缓存还是直接删除缓存? (1)、如果写数据库的值与更新到缓存值是一样的,不需要经过任何的计算,可以马上更新缓存,但是如果对于那...
    99+
    2022-11-11
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作