如何通过redis减库存的秒杀场景实现

 更新时间:2022年06月01日 10:42:34   作者:ZNineSun  
本文通过解决秒杀系统中的一个场景即数据预加载,即把库存数据事先加载到缓存,然后通过缓存来更新库存,简单介绍了如何通过redis减库存的秒杀场景实现,感兴趣的可以了解一下

Redis扣库存,主要目的是减少对数据库的访问,之前的减库存,直接访问数据库,读取库存,当高并发请求到来的时候,大量的读取数据有可能会导致数据库的崩溃。

大家可以先读一下《秒杀系统设计》对整体的秒杀流程有个了解之后,在来读一下这篇文章。

本文只是解决秒杀系统中的一个场景即数据预加载,即把库存数据事先加载到缓存,然后通过缓存来更新库存。

使用思路:

  • 系统初始化的时候,将商品库存加载到Redis 缓存中保存。
  • 收到请求的时候,先在Redis中拿到该商品的库存值,进行库存预减,如果减完之后库存不足,直接返回逻辑Exception就不需要访问数据库再去减库存了,如果库存值正确,进行下一步。
  • 将请求入队,立即给前端返回一个值,表示正在排队中,然后进行秒杀逻辑,后端队列进行秒杀逻辑,前端轮询后端发来的请求,如果秒杀成功,返回秒杀,成功,不成功就返回失败。

第一步:系统初始化后就将所有商品库存放入缓存

/**
 * 秒杀接口优化之---   第一步:  系统初始化后就将所有商品库存放入 缓存
 */
@Override
public void afterPropertiesSet() throws Exception {
    List<GoodsVo> goods = goodsService.getGoodsList();
    if (goods == null) {
        return;
    }
    for (GoodsVo goodsVo : goods) {
        redisService.set(GoodsKey.getId(), goodsVo.getStockCount());
        isOverMap.put(goodsVo.getId(), false);//先初始化 每个商品都是false 就是还有
    }
}

第二步: 预减库存从缓存中减库存

/**秒杀接口优化之 ----第二步: 预减库存 从缓存中减库存
 * 利用 redis 中的方法,减去库存,返回值为 减去1 之后的值
 * */
long stock = redisService.decr(GoodsKey.getGoodsStock, "" + goodsId);
/*这里判断不能小于等于,因为减去之后等于 说明还有是正常范围*/
if (stock < 0) {
    isOverMap.put(goodsId, true);//没有库存就设置 对应id 商品的map 为true
    return Result.error(CodeMsg.MIAO_SHA_NO_STOCK);
}

整体的逻辑如下:

1.先将所有数据读出来,初始化到缓存中,并以 stock + goodid 的形成存入Redis。

2.在秒杀的时候,先进行预减库存检测,从redis中,利用decr 减去对应商品的库存,如果库存小于0,说明此时 库存不足,则不需要访问数据库。直接抛出异常即可。
我们上面还使用到了isOverMap,这个是内存标记。

内存标记

由于接口优化很多基于Redis的缓存操作,当并发很高的时候,也会给Redis服务器带来很大的负担,如果可以减少对Redis服务器的访问,也可以达到的优化的效果。

于是,可以加一个内存map,标记对应商品的库存量是否还有,在访问Redis之前,在map中拿到对应商品的库存量标记,就可以不需要访问Redis 就可以判断没有库存了。

1.生成一个map,并在初始化的时候,将所有商品的id为键,标记false 存入map中。

private Map<Long, Boolean> isOverMap = new HashMap<Long, Boolean>();
/**
 * 秒杀接口优化之---   第一步:  系统初始化后就将所有商品库存放入 缓存
 */
@Override
public void afterPropertiesSet() throws Exception {
    List<GoodsVo> goods = goodsService.getGoodsList();
    if (goods == null) {
        return;
    }
    for (GoodsVo goodsVo : goods) {
        redisService.set(GoodsKey.getGoodsStock, "" + goodsVo.getId(), goodsVo.getStockCount());
        isOverMap.put(goodsVo.getId(), false);//先初始化 每个商品都是false 就是还有
    }
}
/**再优化: 优化 库存之后的请求不访问redis 通过判断 对应 map 的值
  * */
boolean isOver = isOverMap.get(goodsId);
if (isOver) {
     return Result.error(CodeMsg.MIAO_SHA_NO_STOCK);
}

if (stock < 0) {
     isOverMap.put(goodsId, true);//没有库存就设置 对应id 商品的map 为true
}

2.在预减库存之前,从map中取标记,若标记为false,说明库存

3.预减库存,当遇到库存不足的时候,将该商品的标记置为true,表示该商品的库存不足。这样,下面的所有请求,将被拦截,无需访问redis进行预减库存。

所以利用缓存的整体思路如下:

将商品的库存数据加载至内存,同时初始化内存标记,即把每个产品的id存放至map,都是初始化为false,在每次需要执行秒杀逻辑之前,在在内存标记中取值,如果仍有库存即map里返回的为false,则 执行秒杀逻辑,否则直接抛出异常。

同时扣减库存时,需要判断缓存中的库存数量是否仍然大于0,如果小于等于0,修改内存标记。

到此这篇关于如何通过redis减库存的秒杀场景实现的文章就介绍到这了,更多相关redis减库存内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以

相关文章

  • Redis RDB与AOF持久化方式详细讲解

    Redis RDB与AOF持久化方式详细讲解

    Redis是基于内存的数据结构服务器,保存了大量的键值对数据,所以持久化到磁盘是非常必要的,Redis提供了两种持久化的方式,分别是RDB和AOF。下面我们看下这两种持久化方式的具体实现原理
    2022-11-11
  • Redis慢查询日志及慢查询分析详解

    Redis慢查询日志及慢查询分析详解

    这篇文章主要为大家介绍了Redis慢查询日志及慢查询分析详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • redis慢查询日志的访问和管理方式

    redis慢查询日志的访问和管理方式

    这篇文章主要介绍了redis慢查询日志的访问和管理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • redis中Hash字典操作的方法

    redis中Hash字典操作的方法

    redis支持五大数据类型,只支持第一层,也就说字典的value值,必须是字符串,本文主要介绍了redis中Hash字典操作,感兴趣的可以了解一下
    2021-07-07
  • 解决Redis连接无法正常释放的问题

    解决Redis连接无法正常释放的问题

    这篇文章主要介绍了解决Redis连接无法正常释放的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Redis主从复制的原理分析

    Redis主从复制的原理分析

    Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、优化网络带宽等措施,故障转移机制依赖于Sentinel或Cluster组件
    2025-01-01
  • Redis数据库的数据倾斜详解

    Redis数据库的数据倾斜详解

    Redis,英文全称是Remote Dictionary Server(远程字典服务),是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,需要的朋友可以参考下
    2023-07-07
  • Redis 的过期策略与键的过期时间设置方法

    Redis 的过期策略与键的过期时间设置方法

    Redis通过惰性删除和定期删除策略管理内存,提供多种命令设置键的过期时间,并通过过期字典高效处理过期键,合理设置过期时间、监控过期键数量和避免大量键同时过期是最佳实践,本文介绍Redis 的过期策略与键的过期时间设置,感兴趣的朋友一起看看吧
    2025-03-03
  • Redis线程模型的原理分析

    Redis线程模型的原理分析

    Redis是一个高性能的数据存储框架,在高并发的系统设计中,Redis也是一个比较关键的组件,是我们提升系统性能的一大利器,本文详细的介绍了Redis线程模型,感兴趣的可以了解一
    2021-11-11
  • Linux环境下升级redis的详细步骤记录

    Linux环境下升级redis的详细步骤记录

    这篇文章主要给大家介绍了关于Linux环境下升级redis的详细步骤,描述了如何从旧版本升级到新版本Redis,包括备份旧数据、下载和安装新版本、复制配置文件和数据、停止旧版本并启动新版本的过程,需要的朋友可以参考下
    2024-12-12

最新评论