Redis应对高并发的秒杀系统,这里已12306为例

秒杀系统难点:访问的用户突然爆增,系统不堪重负,死机,系统无法访问;超卖,原本只卖100件商品,但现在卖了200件商品;作弊导致一个用户购买了多件商品等问题。
秒杀主要的应用场景包括:预约抢购、限时购、春运12306抢购火车票、某西医院专家号等都属手秒杀范畴。
解决方案:异步、解耦、削峰。
    
首先要说明的是订票系统是个复杂的系统,区分各个省份、低级市等各城市的访问,每个城市的访问量(人口)也不一样,这就需要在接入层做地域的划分,做多机房策略,将流量划分到各个区域。 到第2层的lvs分摊流量到各个子区域服务器,将请求流量进一步缩小,对接到服务器上。

假如我们现在卖10000张北京到上海的火车票,然后我们每台机器本地库存 100 张火车票,100 台服务器上的总库存还是 1 万(lvs层到服务器),这样保证了库存订单不超卖,下面是我们描述的集群架构:

问题接踵而至,在高并发情况下,现在我们还无法保证系统的高可用,假如这 100 台服务器上有两三台机器因为扛不住并发的流量或者其他的原因宕机了。那么这些服务器上的订单就卖不出去了,这就造成了订单的少卖。 要解决这个问题,我们需要对总订单量做统一的管理,这就是接下来的容错方案。服务器不仅要在本地减库存,另外要远程统一减库存。 有了远程统一减库存的操作,我们就可以根据机器负载情况,为每台机器分配一些多余的“Buffer 库存”用来防止机器中有机器宕机的情况。 我们结合下面架构图具体分析一下:

我们采用 Redis 存储统一库存,因为 Redis 的性能非常高,号称单机 QPS 能抗 10W 的并发。 在本地减库存以后,如果本地有订单,我们再去请求 Redis 远程减库存,本地减库存和远程减库存都成功了,才返回给用户抢票成功的提示,这样也能有效的保证订单不会超卖。 当机器中有机器宕机时,因为每个机器上有预留的 Buffer 余票,所以宕机机器上的余票依然能够在其他机器上得到弥补,保证了不少卖。 Buffer 余票设置多少合适呢,理论上 Buffer 设置的越多,系统容忍宕机的机器数量就越多,但是 Buffer 设置的太大也会对 Redis 造成一定的影响。 虽然 Redis 内存数据库抗并发能力非常高,请求依然会走一次网络 IO,其实抢票过程中对 Redis 的请求次数是本地库存和 Buffer 库存的总量。 因为当本地库存不足时,系统直接返回用户“已售罄”的信息提示,就不会再走统一扣库存的逻辑。 这在一定程度上也避免了巨大的网络请求量把 Redis 压跨,所以 Buffer 值设置多少,需要架构师对系统的负载能力做认真的考量。

参考链接:

http//redis.com.cn/redis-intro.html
https://mp.weixin.qq.com/s/hYJFRs-bN-5Z_lF1cQ086w