高并发抢票的启示

本文揭秘了12306系统在高并发场景下的核心技术,包括负载均衡(OSPF、LVS、Nginx)、内存优化、原子操作、数据库事务处理、Redis分布式库存管理和容错机制。通过本地库存和Buffer库存设计,确保服务稳定性与性能优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

博客参考:
12306 支撑百万 qps的核心秘籍

如何在 100 万人同时抢 1 万张火车票时,系统提供正常、稳定的服务。

负载均衡(3层):
1 OSPF(开放式最短链路优先)
2 LVS (Linux Virtual Server)
3 Nginx

(生成订单、减扣库存)原子操作、用户支付。用户五分钟内不支付,订单就失效了,订单一旦失效,就会加入新的库存。

订单的生成是异步的,一般都会放到 MQ、Kafka这样的即时消费队列中处理。

为了保证扣库存和生成订单的原子性,需要采用事务处理,然后取库存判断、减库存,最后提交事务,整个流程有很多IO,对数据库的操作又是阻塞的。

这种方式根本不适合高并发的秒杀系统。接下来我们对单机扣库存的方案做优化:本地扣库存。

我们把一定的库存量分配到本地机器,直接在内存中减库存,然后按照之前的逻辑异步创建订单。

这样就避免了对数据库频繁的IO操作,只在内存中做运算,极大的提高了单机抗并发的能力。但是百万的用户请求量单机是无论如何也抗不住的。

Linux 系统下,一切资源皆文件,网络请求也是这样,大量的文件描述符会使操作系统瞬间失去响应。

Nginx的加权均衡策略,我们不妨假设将 100W 的用户请求量平均均衡到 100 台服务器上,这样单机所承受的并发量就小了很多。然后我们每台机器本地库存 100 张火车票,100 台服务器上的总库存还是 1 万。

问题接踵而至,在高并发情况下,现在我们还无法保证系统的高可用,假如这 100 台服务器上有两三台机器因为扛不住并发的流量或者其他的原因宕机了。那么这些服务器上的订单就卖不出去了,这就造成了订单的少卖。

要解决这个问题,我们需要对总订单量做统一的管理,这就是接下来的容错方案。服务器不仅要在本地减库存,另外要远程统一减库存。

有了远程统一减库存的操作,我们就可以根据机器负载情况,为每台机器分配一些多余的Buffer库存用来防止机器中有机器宕机的情况。

我们采用 Redis 存储统一库存,因为 Redis 的性能非常高,号称单机 QPS 能抗 10W 的并发。

在本地减库存以后,如果本地有订单,我们再去请求 Redis 远程减库存,本地减库存和远程减库存都成功了,才返回给用户抢票成功的提示,这样也能有效的保证订单不会超卖。

redis只会被扣除1w次,因为只有1w张票。相当于查从redis迁移到了内存,只有改才会去访问redis。

在这里插入图片描述

当机器中有机器宕机时,因为每个机器上有预留的Buffer余票,所以宕机机器上的余票依然能够在其他机器上得到弥补,保证了不少卖。

Buffer余票设置多少合适呢,理论上Buffer设置的越多,系统容忍宕机的机器数量就越多,但是Buffer设置的太大也会对Redis 造成一定的影响。

虽然Redis内存数据库抗并发能力非常高,请求依然会走一次网络IO,其实抢票过程中对Redis的请求次数是本地库存和Buffer 库存的总量(设置多了的话就会多请求redis,比如本来10w张票,应该只请求10w次redis的,结果请求了15w次)。

因为当本地库存不足时,系统直接返回用户“已售罄”的信息提示,就不会再走统一扣库存的逻辑。

这在一定程度上也避免了巨大的网络请求量把Redis压跨,所以Buffer值设置多少,需要架构师对系统的负载能力做认真的考量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

六边形战士666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值