当前位置:首页 > 问答 > 正文

用Redis秒杀列队搞定瞬时抢购,购物体验飞起来了

(引用来源:网络技术博客、电商平台技术分享案例)

还记得以前网上抢购热门商品的那种感觉吗?比如一部新手机首发,或者一张很难买的演唱会门票,时间一到,你早早守在电脑前,疯狂点击“立即购买”按钮,结果页面要么卡死不动,转了半天圈,最后显示一个刺眼的“系统繁忙”;要么好不容易挤进去,却发现库存已经归零,那种感觉,就像参加一场没有秩序的混乱挤兑,拼的不是手速和网速,更像是运气,这不仅让用户非常沮丧,服务器可能因为瞬间的巨大流量而崩溃,导致整个网站都无法访问,损失更大。

后来,我听一些做技术的朋友聊起,他们用了一种叫Redis的技术来解决这个问题,效果特别神奇,Redis你可以把它理解成一个超级快的“临时记事本”,它运行在服务器的内存里,所以读写速度比去硬盘上的数据库里查东西要快成千上万倍,秒杀的核心难题就是“瞬时高并发”,即在极短的时间内(比如一秒内)有几十万甚至上百万人同时来抢购数量有限的商品,如果用传统的方式,每一个请求都要去数据库里查询库存、再减库存,数据库根本扛不住这么大的压力,就像让一个收银员在几分钟内处理完一个体育馆所有人的购票请求,肯定会瘫痪。

用Redis秒杀列队搞定瞬时抢购,购物体验飞起来了

而用Redis的队列功能,思路就完全变了,它的做法非常聪明,可以概括为“先排队,后办事”,在秒杀开始前,系统就提前把比如1000件商品的库存数量,转化成1000个“令牌”,并预先存放到Redis这个高速的队列里,每一个令牌就代表一件商品的购买资格,这个过程就像电影院提前把所有的票都打印好,放在售票窗口的盒子里。

当秒杀活动正式开始,百万用户同时点击抢购按钮时,他们的请求并不会直接去冲击核心的数据和库存系统,而是由一个简单的接口接收下来,这个接口只做一件事:就是去Redis的那个队列里,尝试“弹出”一个令牌,因为Redis速度极快,它处理这种“取一个东西”的请求能力非常强,这个操作是原子性的,意思是说它要么成功取出一个,要么因为队列空了而失败,绝对不会出现两个人拿到同一个令牌的情况,这就从根儿上解决了超卖的问题。

用Redis秒杀列队搞定瞬时抢购,购物体验飞起来了

如果用户成功从队列里拿到了一个令牌,那恭喜他,意味着他抢购成功了,系统这时会快速给用户返回一个“抢购成功,请尽快付款”的页面提示,同时把这个成功的请求和用户信息记录到另一个地方,比如一个消息队列里,告诉后台系统:“喂,这里有个人成功了,你稍后慢慢处理他的下单流程。”这样一来,最紧张、最关键的“抢资格”环节就在一瞬间完成了,耗时可能就十几毫秒,用户几乎感觉不到延迟,体验自然就“飞起来”了。

反过来,如果用户点击按钮时,Redis里的令牌已经被抢光了,队列是空的,那么系统也会立刻返回“已售罄”的提示,因为没有去折腾复杂的数据库,这个失败的结果返回得也极其迅速,用户不用再苦苦等待页面转圈,能马上知道结果,虽然失望,但至少过程是干脆利落的。

你看,通过引入Redis这个高速队列,整个抢购过程的核心压力都被它承担了,它就像一个经验丰富的交通警察,在流量洪峰到来时,高效地指挥着每一个请求,让它们迅速有序地通过最拥堵的路口(判断库存资格),然后再分流到后台去处理后续不那么紧急的事情(生成订单、扣款等),对于用户来说,最直观的感受就是页面响应飞快,点击按钮后结果立竿见影,抢购体验从以前的“折磨”变成了现在的“爽快”,而对于商家而言,系统变得更加稳定,再也不用担心因为一个秒杀活动而导致整个网站宕机,实现了双赢,这就是技术巧妙应用带来的实实在在的体验提升。