Redis支撑秒杀场景应用

秒杀是一个非常典型的常见,比如像双11,618这样的网络购物节,一些平台会提供限时限量的是商品,而且这些商品也是物美价廉,吸引大量的用户,redis经常用于这种秒杀场景

我们先来谈谈秒杀场景的特点对支持系统的要求

秒杀场景的特点及redis对秒杀场景的支持

  • 瞬时并发访问量非常高

秒杀最明显的特哥特点就是瞬时访问量巨大,对于数据来说,所能够支撑的访问量也就是每秒千级别,而redis本身的特点就是高性能的读写,可以处理每秒万级别的请求,甚至更高。所以我们可以使用redis拦截绝大部分的请求,这样数据库的压力就大大减轻。

  • 读多写少,而且都是简单的查询

在秒杀场景中,正常操作是先通过商品id查询库存,判断库存是否有余,然后是扣减库存。商品的数量是有限的,所以真正扣减库存的操作也是有限,更多是查询库存信息,用户每次点击抢购都会有查询库存操作。查询库存操作是典型的键值操作,redis对键值对查询的搞笑支持,刚好满足这一点。

redis在秒杀场景中的哪些环节发生作用

秒杀的整个过程,我们可以分为三个部分:

  1. 秒杀活动前
  2. 秒杀活动中
  3. 秒杀活动后

下面我们就详细极少一下各个环节redis的作用

秒杀活动前

在这个阶段,用户会不断的刷新商品详情页,这就会给服务端造成巨大的压力。我们一般采用的方法就是商品详情的信息尽量静态化,先缓存到cdn或者利用浏览器的缓存,这样就不会有大量的请求到服务端,减少了服务端的压力。在这一阶段不需要用到redis。

秒杀活动中

在这一阶段,需要做一些操作:查询库存,校验库存是否充足,扣减库存。因为每一个请求都需要查询库存,所以查询库存的压力就会很大,库存校验成功之后才会有扣减库存操作。此时我们就需要使用redis来缓存库存信息,来支持大量的查询库存请求。

扣减库存是否可以在数据库端完成?

答案是否定的不能,原因如下:

1:如果在数据库中扣减库存,那么数据库中库存扣减成功之后,还需要更新redis中的库存,增加了操作的复杂度

2:有可能会出现超卖的情况,比如数据库中库存扣减成功,但是还未来得及更新redis中的库存,那么就会读取到redis中的旧库存,导致超卖。

综上扣减库存操作还是需要放在redis中。

需要注意的是查询库存,校验库存是否充足,扣减库存,这三个步骤我们要保证原子性操作,不然查询可能会查到旧库存,导致超卖。保证原子性我们我们有三种做法:

1:使用redis自带的操作命令。目前来看没有相关命令,所以pass掉

2:使用lua脚本,可以保证操作的原子性。lua的伪代码如下


#获取商品库存信息            
local counts = redis.call("HMGET", KEYS[1], "total", "ordered");
#将总库存转换为数值
local total = tonumber(counts[1])
#将已被秒杀的库存转换为数值
local ordered = tonumber(counts[2])  
#如果当前请求的库存量加上已被秒杀的库存量仍然小于总库存量,就可以更新库存         
if ordered + k <= total then
    #更新已秒杀的库存量
    redis.call("HINCRBY",KEYS[1],"ordered",k)                              
    return k;  
end               
return 0

3:使用分布式锁,用户需要先获取锁才能进行库存查询,及以后操作。伪代码如下:


//使用商品ID作为key
key = itemID
//使用客户端唯一标识作为value
val = clientUniqueID
//申请分布式锁,Timeout是超时时间
lock =acquireLock(key, val, Timeout)
//当拿到锁后,才能进行库存查验和扣减
if(lock == True) {
   //库存查验和扣减
   availStock = DECR(key, k)
   //库存已经扣减完了,释放锁,返回秒杀失败
   if (availStock < 0) {
      releaseLock(key, val)
      return error
   }
   //库存扣减成功,释放锁
   else{
     releaseLock(key, val)
     //订单处理
   }
}
//没有拿到锁,直接返回
else
   return

秒杀活动后

活动结束后可能还有有部门用户刷新商品页面,看是否有其他客户退单。已经成功的用户查看订单信息,跟踪订单的进度,但这些用户的请求量已经小很多了,服务器可以支持。

 

 

 

 

 

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值