【Redis】电商项目秒杀问题之下单接口优化:Redis缓存、MQ以及lua脚本优化高并发背景下的秒杀下单问题 | 您所在的位置:网站首页 › 脚本秒杀软件 › 【Redis】电商项目秒杀问题之下单接口优化:Redis缓存、MQ以及lua脚本优化高并发背景下的秒杀下单问题 |
目录 一、优化思路 二、缓存库存与订单 1、库存缓存的redis数据结构 2、订单信息缓存的redis数据结构 三、整体流程 四、lua脚本确保权限校验操作的原子性 一、优化思路【Redis】电商项目秒杀问题之超卖问题与一人一单问题_1373i的博客-CSDN博客 【RabbitMQ】初识消息中间件MQ_1373i的博客-CSDN博客 库存的缓存使用string就可以了,不过在缓存的时候key需要注意他的命名,在我们使用缓存时也要注意缓存时key的命名,要有区分度比如:业务名+特定信息 2、订单信息缓存的redis数据结构这里的订单信息缓存我们主要使用它来判断用户是否已经下单所以此处缓存没有必要将所有的订单信息都缓存进来,此处我们只需要缓存用户id即可,在查询时查询该用户id是否存在即可判断,此时我们可以使用set来存储订单信息,key为业务order+商品id,value为购买过该商品的用户id,由于set数据结构的特点,当用户已经下过单时,在进行用户id存入该缓存时如果已经下过单了就会存入失败,以此来判断用户是否下过单 上述流程还存在线程安全问题,即上述查询库存以及查询缓存订单信息与扣减缓存库存这一系列操作不是原子性的,那么我们可以通过lua脚本来保证上述操作的原子性以此保证线程安全。 所有整体的秒杀流程如下图:请求到服务器时先执行用户购买权限校验的lua脚本,拿到脚本执行的结果后判断是否满足下单操作,如果满足则将订单信息存入MQ并返回订单id 首先我们在使用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)) |
CopyRight 2018-2019 实验室设备网 版权所有 |