Redis 支撑秒杀场景的关键技术和实践都有哪些?


秒杀是一个非常典型的活动场景,比如,在双 11、618 等电商促销活动中,都会有秒杀场景。秒杀场景的业务特点是限时限量,业务系统要处理瞬时的大量高并发请求,而 Redis 就经常被用来支撑秒杀活动。

不过,秒杀场景包含了多个环节,可以分成秒杀前、秒杀中和秒杀后三个阶段,每个阶段的请求处理需求并不相同,Redis 并不能支撑秒杀场景的每一个环节。

秒杀场景的负载特征对支撑系统的要求

第一个特征是瞬时并发访问量非常高。

一般数据库的并发访问量在千级别,而 Redis 的并发访问量在万级别,甚至更高。

第二个特征是读多写少

Redis 可以在秒杀场景的哪些环节发挥作用?

如果将秒杀分为三个阶段,分别是秒杀前,秒杀中和秒杀后

秒杀前

秒杀前一般都是读操作,比如读取商品页信息。秒杀前可以将页面元素静态化,然后使用CDN或是浏览器把这些静态化的元素缓存起来。访问的时候直接访问缓存,这样做可以减轻秒杀前对服务器的冲击。

秒杀中

此时,大量用户点击商品详情页上的秒杀按钮,会产生大量的并发请求查询库存。一旦某个请求查询到有库存,紧接着系统就会进行库存扣减。然后,系统会生成实际订单,并进行后续处理,例如订单支付和物流服务。如果请求查不到库存,就会返回。用户通常会继续点击秒杀按钮,继续查询库存。

简单来说,这个阶段无非就是三个简单操作,库存查验,扣库存,订单处理。

而这三个操作中压力最大的就是库存查验。因为扣库存和订单处理这些操作都是抢到商品的用户,秒杀用户量肯定是少的。

注意:为了避免查验库存查到旧值,查验库存和扣减库存这两个操作需要保证原子性。而处理订单这个环节涉及到多张表,操作比较繁琐,这个时候我们可以使用消息队列等技术来进行处理。

秒杀后

在这个阶段仍有少部分人在刷新商品页,也就是查验库存,这部分人在等之前抢到商品但是取消订单或者是没有支付系统自动取消的这部分人的库存。但是这个阶段人数肯定很少了,服务器一般能够支撑的住。

下面来重点说秒杀中这部分

Redis 的哪些方法可以支撑秒杀场景?

基于原子操作支撑秒杀场景

查验库存和扣减库存这两个操作需要保证原子性。怎么保证这两个操作的原子性呢?

由于涉及到又查又减的操作,Redis 中没有提供单命令与之相关的单命令操作。

此时我们可以借助 Lua 脚本来完成这一需求。Lua 脚本可以保证原子性。

有了 Lua 脚本后,我们就可以在 Redis 客户端,使用 EVAL 命令来执行这个脚本了。

其实还有另一种技术,是使用分布式锁来解决这一需求。

基于分布式锁来支撑秒杀场景

使用分布式锁的具体做法就是:先让 Redis 客户端向 Redis 申请分布式锁,只有拿到锁的客户端才能够对库存进行查验库存和扣减库存的操作。这样一来,大量的请求就会在竞争分布式锁的时候被过滤掉(截流)。而且,库存查验和扣减也不用使用原子操作了,因为多个并发客户端只有一个客户端能够拿到锁,已经保证了客户端并发访问的互斥性。

注意:使用分布式锁要注意因为一些特殊原因没有及时释放锁的这样一个 case。因为没有一旦客户端因为一些特殊原因,比如对 共享资源 也就是库存处理的时候出现bug导致没有及时释放锁,会导致其他客户端也拿不到锁,谁都拿不到锁,那么谁都别想处理共享资源了。

解决办法:给 锁变量 设置一个过期的时间就ok了!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值