现在redis真的非常流行,曾经有朋友跟我吐槽招人好难,他本身是从大厂出来的,问得太细的几乎没人知道,问得太浅又不知道这个人的真实水平。我跟他说,没事,一般问一下会写JAVA会使用Redis,就能拉出来干活了,掌握了这两个技能,一般都不会太差。
今天我们来谈一谈Redis的队列的应用,如何2个小时,搭建一个数十万并发的电商优惠券领券系统。这是一个真实的故事,当年我们还是一个非常小的创业电商团队,有一天,老板过来说今天下午中国移动会在多个渠道推广我们的App,具体的形式就是领优惠券。预计的QPS有好几万。
我们的优惠券是属于一卡一码型的,就是一张优惠券都有一个优惠码,用户可以用该优惠码到我们的APP上面进行激活。用户领券的时候,我们需要去数据库里面拉一个还未被使用的优惠码,如果捞到的二维码被别人使用了,那么就需要重试,性能比较差。
看起来有两个比较明确的优化方向,一是采用一定策略从数据库里面捞数据,减少不同机器不同线程捞到同一个券码的可能,避免冲突,二是在内存里面维护一个队列,减少访问数据库的次数。
当时距离活动开始已经不到5个小时,按照上面的方向去优化,开发、测试、压测的时间已经是非常紧张了,风险相当大。我们迫切需要一种更简单的方案来解决。
这个时候,万金油Redis又出马了。Redis提供一种实用的数据结构,叫双端队列。在日常开发中,我们常常可以把它当成分布式队列来用。Redis队列提供lpush,lpop,rpush,rpop等基本的操作,可以从队列中取出对应的元素。这里可能有人会问,需要加锁么?会不会两个进程取到同一个元素,并不会,因为Redis是单线程的,所以很安全。
在上述场景下,我们先把全量的优惠券券码从数据库里面加载到Redis里面,为了避免Redis的单点故障,我们可以分批放到2个实例,每次用户调用领券接口的时候,先从Redis的队列中取一个券码出来,然后再Update到数据库即可,如果担心数据库扛不住,可以先写到Redis中。这个开发起来非常简单,在原来的接口上面改改半个小时就能撸完代码上线了。
今天的介绍我们就讲到这里,有没有学习到Redis新的姿势呢,后面我们再继续将Redis的一些命令与应用。如果你有兴趣,欢迎关注我,主讲算法相关的,近期还准备了一些AI相关的知识,整理后会和大家继续分享。大家的支持是我继续唠嗑的动力。