Redis 实现高并发库存扣减方案

背景

公司的电商系统下单 操作库存是一个频繁操作,需要高效地扣减库存,把对销售库存的操作抽出来独立设计一个库存中心系统。
功能包括库存的批量添加、获取、下单、支付、回退等的操作。

解决的业务痛点
  • 需要高效
  • 不超卖
方案
一、使用msql乐观锁

额外增加一个字段,并利用mybatisplus 注解@Version,可以方便地利用乐观锁的方式来操作库存。

这种方式当多个并发碰到一起时,只有一个版本的线程能拿到数据操作,并且要对数据库不断进行查询和修改的io操作,不合适,性能也不好。

二、使用分布式锁

直接加锁本质上是对竞争资源的线程进行排队处理,保证了并发时数据扣减不出错,但直接操作db效率肯定也不高。

三、放在redis操作

大概思路是,把操作库存的动作放在redis操作,(无论是下单扣减,还是回退,添加库存等)redis操作完毕发一个mq消息,然后就可以给上游服务响应了。后续的db扣除操作在消费mq时mysql慢慢消化就行。
在这里插入图片描述
上图展示了下单场景时的时序图。支付、撤销、添加库存等操作原理类似。这样的话库存是以redis为准了。

要点:
  • 创建商品时,db保存库存,并把库存同步到redis作为预热的缓存。
  • 下单时 可以多插入一个【多顶库存记录表】,并开启事务,这个表主要是用来记录操作库存的日志的,用来后续如果有问题可以对照(业务兜底)。因为都是insert 操作,没有update数据库行记录,不会有资源竞争所以效率还好,主键必须设置为长整型,并且自动递增。(这个步骤可以根据业务不增加可以进一步提高并发)。
  • 消费mq真正对db的库存操作时,可以先对当前sku的redis缓存增加缓存有效时间,相当于给当前操作的sku缓存续命,防止缓存在处理时失效导致redis的数据和db的库存不一致。
  • 消费端消费mq消息时要 对每个sku要加分布式锁的处理,保证数据的正确。
  • 我是用lua脚本的方式让库存的操作在redis那边也保证原子执行。因为我的库存有 可用库存、锁定库存、已售库存,所以我用redis的hash数据结构存储:
    在这里插入图片描述

可以看到每个操作都写了两个lua脚本目的是为了提高下效率,先查询一下(check),因为是批量操作,如果有不符合要求的直接返回了,不用等到执行一半再返回。

  • 还有一点要注意因为redis在生产是部署在集群环境,想要key落在同一个槽中,key的名字要加{}即可,否则会报错
    在这里插入图片描述
  • 集群环境下同一个lua脚本中不能操作两个不同槽的key的数据(即两个用不同大括号括起来的key),否则也会报错
    在这里插入图片描述

相关推荐

  1. 001 redis并发库存

    2024-07-10 13:58:01       18 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-10 13:58:01       4 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-10 13:58:01       5 阅读
  3. 在Django里面运行非项目文件

    2024-07-10 13:58:01       4 阅读
  4. Python语言-面向对象

    2024-07-10 13:58:01       5 阅读

热门阅读

  1. 使用Spring Cloud构建微服务架构下的淘客返利系统

    2024-07-10 13:58:01       8 阅读
  2. TCP/IP协议族结构和协议

    2024-07-10 13:58:01       10 阅读
  3. 重读AI金典算法模型-GPT系列

    2024-07-10 13:58:01       9 阅读
  4. win10使用小技巧三

    2024-07-10 13:58:01       9 阅读
  5. 根据关键词query获取google_img(api方式)

    2024-07-10 13:58:01       7 阅读
  6. redis中的事务和mysql中的事务有什么区别?

    2024-07-10 13:58:01       11 阅读
  7. C# 构造函数依赖注入 使用out向外传递参数

    2024-07-10 13:58:01       12 阅读
  8. 信息时代,呼唤新的哲学

    2024-07-10 13:58:01       10 阅读
  9. 【数据基础】— B树

    2024-07-10 13:58:01       9 阅读
  10. Vue 路由传参 query方法 bug 记录

    2024-07-10 13:58:01       9 阅读
  11. 翻页 上一页/下一页

    2024-07-10 13:58:01       11 阅读