【Redis】电商项目秒杀问题之下单接口优化:Redis缓存、MQ以及lua脚本优化高并发背景下的秒杀下单问题

这篇具有很好参考价值的文章主要介绍了【Redis】电商项目秒杀问题之下单接口优化:Redis缓存、MQ以及lua脚本优化高并发背景下的秒杀下单问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、优化思路

二、缓存库存与订单

1、库存缓存的redis数据结构

2、订单信息缓存的redis数据结构

三、整体流程

四、lua脚本确保权限校验操作的原子性


一、优化思路

【Redis】电商项目秒杀问题之超卖问题与一人一单问题_1373i的博客-CSDN博客https://blog.csdn.net/qq_61903414/article/details/130568972?spm=1001.2014.3001.5501在之前的文章里解决了电商项目项目超卖与一人一单的一些线程安全问题,之前的操作大体流程是:下单请求到达服务器,服务器会先查询库存是否足够,如果足够则继续判断用户是否已经下过单,如果没有下过单则去进行后续扣减库存生成订单这些操作我,完成后返回给客户端。如果在高并发情况下该接口的性能是相对较低的,因为上述操作有许多数据库的读写操作,只有等这些操作完成后我们才能返回响应,那么怎么去优化响应速度呢?【Redis】电商项目秒杀问题之下单接口优化:Redis缓存、MQ以及lua脚本优化高并发背景下的秒杀下单问题

【RabbitMQ】初识消息中间件MQ_1373i的博客-CSDN博客https://blog.csdn.net/qq_61903414/article/details/130138361?spm=1001.2014.3001.5501在之前RabbitMQ的文章中我们有提到MQ的优点,有一个就是异步提速,这里我们可以借鉴这一思路,异步的去处理一些操作。上述的操作其实主要分为两类,一类是对用户是否有购买权限的校验,还有一类是执行后续下单操作。这两类的关系是首先你必须得有购买权限才能去执行后续操作,那么现在我们可以将权限校验这一部分操作提取处理,请求到达服务器后先去进行用户是否有购买权限的校验,也就是先判断库存是否足够与用户是否已下单,如果用户满足购买要求则直接将订单号返回给前端,然后将该订单存入一个阻塞队列中,开启一个扫描线程,扫描该队列异步的去处理后续下单操作,但是此处值得注意的是我们如果使用Java中的阻塞队列的化,其实性能也不一定会提高,因为他是占用jvm资源的,所以我们可以使用RabbitMQ等这些消息队列中间件,我们可以使用redis来实现消息队列的效果,在后续的文章会讲到。现在我们对下单操作进行了优化,此时我们还可以对用户购买权限的校验进行优化,这两个操作都是去查询数据库的,在前面的文章里我们学习了redis缓存的使用,所以我们可以使用redis做缓存将商品的库存与订单信息缓存到redis中,此时请求到服务器后会去redis中获取到库存如果足够,在从redis中查询订单信息是否已存,如果存在则将redis中的库存进行扣减,然后加入订单缓存,将该订单号返回客户端,将订单信息交给MQ异步的去处理扣减数据库库存。

二、缓存库存与订单

1、库存缓存的redis数据结构

库存的缓存使用string就可以了,不过在缓存的时候key需要注意他的命名,在我们使用缓存时也要注意缓存时key的命名,要有区分度比如:业务名+特定信息

2、订单信息缓存的redis数据结构

这里的订单信息缓存我们主要使用它来判断用户是否已经下单所以此处缓存没有必要将所有的订单信息都缓存进来,此处我们只需要缓存用户id即可,在查询时查询该用户id是否存在即可判断,此时我们可以使用set来存储订单信息,key为业务order+商品id,value为购买过该商品的用户id,由于set数据结构的特点,当用户已经下过单时,在进行用户id存入该缓存时如果已经下过单了就会存入失败,以此来判断用户是否下过单【Redis】电商项目秒杀问题之下单接口优化:Redis缓存、MQ以及lua脚本优化高并发背景下的秒杀下单问题

三、整体流程

上述流程还存在线程安全问题,即上述查询库存以及查询缓存订单信息与扣减缓存库存这一系列操作不是原子性的,那么我们可以通过lua脚本来保证上述操作的原子性以此保证线程安全。

所有整体的秒杀流程如下图:请求到服务器时先执行用户购买权限校验的lua脚本,拿到脚本执行的结果后判断是否满足下单操作,如果满足则将订单信息存入MQ并返回订单id【Redis】电商项目秒杀问题之下单接口优化:Redis缓存、MQ以及lua脚本优化高并发背景下的秒杀下单问题

四、lua脚本确保权限校验操作的原子性

首先我们在使用Java操作redis执行该lua脚本时先要考虑该脚本需要哪些参数呢,我们要判断库存是否足够,就需要传入该商品的信息,然后我们需要判断用户是否已经下过单就需要知道该用户的id,所以我们需要知道商品的id与用户的id

-- 获取参数
-- 1.商品id
local productId = ARGV[1];
-- 2.用户id
local userId = ARGV[2];

-- 构造缓存的key
-- 1.订单key
local orderKey = "secKill:order" .. productId;
-- 2.库存id
local stockKey = "secKill:stock" .. productId;

-- 判断库存是否足够
if (tonumber(redis.call('get',stockKey)) <= 0) then
    -- 库存不足 返回1
    return 1;
end

-- 判断是否下过单
if (redis.call('sismember',orderKey,userId) == 1) then
    -- 存在 返回2
    return 2;
end

-- 满足扣减库存
redis.call('incrby',stockKey,-1);
-- 下单:缓存订单中加入该用户
redis.call("sadd",orderKey,userId);
return 0;

然后我们可以在Java中调用API执行这段lua脚本文章来源地址https://www.toymoban.com/news/detail-451926.html

到了这里,关于【Redis】电商项目秒杀问题之下单接口优化:Redis缓存、MQ以及lua脚本优化高并发背景下的秒杀下单问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Redis:原理速成+项目实战——Redis实战7(优惠券秒杀+细节解决超卖、一人一单问题)

    👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:Redis:原理速成+项目实战——Redis实战6(封装缓存工具(高级写法)缓存总结) 📚订阅专栏:Redis:原理速成+项目实战 希望文章对你们有所帮助 这篇文章写了很久。我自己在边实现、边用

    2024年01月24日
    浏览(98)
  • 华为云应用中间件DCS系列—Redis实现(电商网站)秒杀抢购示例

    云服务、API、SDK,调试,查看,我都行 阅读短文您可以学习到:应用中间件系列之Redis实现(电商网站)秒杀抢购示例 华为云开发者插件(Huawei Cloud Toolkit),作为华为云围绕其产品能力向开发者桌面上的延伸,帮助开发者快速在本地连接华为云,打通华为云到开发者的最后

    2024年02月07日
    浏览(40)
  • Redis优化和解决缓存问题

    目录 redis的2种持久化方式 RDB持久化 AOF持久化 redis优化 redis的三大缓存问题 缓存雪崩的解决方案: 缓存穿透的解决方案: 缓存击穿的解决方案: 如何保证 MySQL 和 redis 的数据一致性? redis的2种持久化方式 RDB持久化 :定时把redis内存中的数据进行快照并压缩保存到硬盘里 手

    2024年01月23日
    浏览(51)
  • 【Redis】缓存常见问题及优化方案

    Redis作为一款高性能的缓存数据库,被广泛应用于各种互联网应用中。然而,在使用过程中,我们可能会遇到一些常见问题,如缓存穿透、缓存击穿、缓存雪崩等。如果忽视这些情况可能会带来灾难性的后果,下面主要对这些缓存异常和常见处理方案进行相应分析与总结。

    2024年01月23日
    浏览(65)
  • 5. Redis优化秒杀、Redis消息队列实现异步秒杀

    承接Redis - 优惠券秒杀、库存超卖、分布式锁、Redisson文章 代码中有大量数据库的操作,整个业务性能并不是很好 平均耗时达到了497毫秒 首先回顾一下之前秒杀业务的流程 前端发起请求到达我们的Nginx,然后Nginx会把我们的请求负载均衡到我们的tomcat 而在tomcat中执行各种逻辑

    2024年02月13日
    浏览(40)
  • Redis【实战篇】---- 秒杀优化

    我们来回顾一下下单流程 当用户发起请求,此时会请求nginx,nginx会访问到tomcat,而tomcat中的程序,会进行串行操作,分成如下几个步骤 1、查询优惠卷 2、判断秒杀库存是否足够 3、查询订单 4、校验是否是一人一单 5、扣减库存 6、创建订单 在这六步操作中,又有很多操作是

    2024年02月12日
    浏览(39)
  • redis实战-redis实现异步秒杀优化

    当用户发起请求,此时会请求nginx,nginx会访问到tomcat,而tomcat中的程序,会进行串行操作,分成如下几个步骤 1、查询优惠卷 2、判断秒杀库存是否足够 3、查询订单 4、校验是否是一人一单 5、扣减库存 6、创建订单  在这六步操作中,又有很多操作是要去操作数据库的,而且

    2024年02月07日
    浏览(42)
  • 《Redis实战篇》六、秒杀优化

    6.0 压力测试 目的 :测试1000个用户抢购优惠券时秒杀功能的并发性能~ ①数据库中创建1000+用户 这里推荐使用开源工具:https://www.sqlfather.com/ ,导入以下配置即可一键生成模拟数据 ②将1000个用户处于登录状态(本质就是为1000个用户生成token,并保存到Redis中) ③在Jmeter中进行压

    2024年01月22日
    浏览(40)
  • Redis 性能管理/优化 双一致性问题 缓存雪崩/击穿/穿透

    used_memory_rss:是Redis向操作系统申请的内存。 used_memory:是Redis中的数据占用的内存。 mem_fragmentation_ratio:内存碎片率。 used_memory_peak:redis内存使用的峰值。 内存碎片如何产生的? Redis内部有自己的内存管理器,为了提高内存使用的效率,来对内存的申请和释放进行管理。

    2024年02月11日
    浏览(49)
  • Redis项目实战——优惠券秒杀

    如果用MySQL的自增长ID,ID的规律性太明显, 会暴漏一些信息 (比如销量等) 数据量太大时一张表存不下,需要多张表,MySQL多张表的自增长都是独立的, 会出现重复ID 需要一种在分布式系统下可以生成全局唯一ID的工具,必须唯一且递增 在某项目里,不管数据库的表有多少

    2024年02月10日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包