当前位置:Gxlcms > PHP教程 > 淘宝商品秒杀的架构在设计过程中需要考虑到那些问题,需要应用到哪些技术?

淘宝商品秒杀的架构在设计过程中需要考虑到那些问题,需要应用到哪些技术?

时间:2021-07-01 10:21:17 帮助过:12人阅读

回复内容:

1. 秒杀活动的技术挑战
假设某网站秒杀活动只推出一件商品,预计会吸引1万人参加活动,也就说最大并发请求数是10000,秒杀系统需要面对的技术挑战有:
对现有网站业务造成冲击
秒杀活动只是网站营销的一个附加活动,这个活动具有时间短,并发访问量大的特点,如果和网站原有应用部署在一起,必然会对现有业务造成冲击,稍有不慎可能导致整个网站瘫痪。
高并发下的应用、数据库负载
用户在秒杀开始前,通过不停的刷新浏览器页面以保证不会错过秒杀,这些请求如果按照一般的网站应用架构,访问应用服务器、连接数据库,会对应用服务器、数据库服务器造成极大的负载压力。
突然增加的网络及服务器带宽
假设商品页面大小200K(主要是商品图片大小),那么需要的网络和服务器带宽是2G(200K×10,000),这些网络带宽是因为秒杀活动新增的,超过网站平时使用的带宽。
直接下单
秒杀的游戏规则是到了秒杀时间才能开始对商品下单购买,在此时间点之前,只能浏览商品信息,不能下单。而下单页面也是一个普通的URL,如果得到这个URL,不用等到秒杀开始就可以下单了。
2. 秒杀系统的应对策略
为了应对上述挑战,秒杀系统的策略有:
秒杀系统独立部署
为了避免因为秒杀活动的高并发访问而拖垮整个网站,使整个网站不必面对蜂拥而来的用户访问,将秒杀系统独立部署,如果需要,还可以使用独立的域名,以和网站完全隔离,即使秒杀系统崩溃了,也不会对网站造成任何影响。
秒杀商品页面静态化
秒杀商品页面重新设计,不使用网站原来的商品详情页面,页面内容静态化:商品描述,商品参数,成交记录,用户评价全部写入一个静态页面,用户请求不需要经过应用服务器的业务逻辑处理,也不需要访问数据库。所以秒杀商品服务不需要部署动态的Web服务器、数据库服务器。
租借秒杀活动网络带宽
对于因为秒杀新增的网络带宽,必须和运营商重新购买或者租借。为了减轻网站服务器的压力,需要将秒杀商品页面缓存在CDN,同样需要和CDN服务商临时租借新增的出口带宽。
动态生成随机下单页面URL
为了避免用户直接访问下单页面URL,需要将该URL动态化,即使秒杀系统的开发者也无法在秒杀开始前访问下单页面的URL。办法是在下单页面URL加入由服务器端生成的随机数作为参数,在秒杀开始的时候才能得到。
3. 秒杀系统架构设计

--摘自《大型网站技术架构》t.cn/z8N27YQ 让我设计的话,可能会用队列,时间一到就开始往队列里放,取队列是单线程,队列设置长度限制,上限就是商品数,如果消费线程发现商品已经卖完了,就通知前端停止接收新请求。 本人并没有参与过淘宝的秒杀系统设计。以下内容都是我设想的,而且只谈概念,这玩意谈概念就行了,具体实现随便找点就可以有很多种。

秒杀的核心问题在于全局和原子性操作,这基本上是反潮流的,现在的潮流不管是数据库系统或者是消息系统都是分布式的,比如Greenplum或者Kafka,再有Redis

这些系统有个巨大问题就是在分布式的场景下做到时序是很困难,或者说代价很大,或者说,没啥必要。

但秒杀系统却不是如此,这种场景需要时序。单点设计也许是必然的。

为此,你首先需要知道的并不是什么大规模网站,超高PV网站所需要了解的那些HTTP优化,数据库优化之类的话题,你需要知道的是短板在哪里,这个场景下,短板是这个可能存在单点。

首先,你需要知道你的极限是什么,这里设计两点:
  1. 极限峰值
  2. 完整持久化,备份所需要的代价
第一个问题,你可以设计一个程序尝试一下,往一个有网络传输的前提下往一个Hash里面不断加入纪录并且拒绝并行化能承担的最大TPS, 个人估计,应该在几万这样的当量上。
这里是不包含磁盘写入或备份传输的,因为这些你可以事后做,而不必要在秒杀当时做。这里有个矛盾,如果你的这个单点是持续高负载,导致你持久化无法持续完成,那你只能拿一条写一条。为此,你会付出很多代价。同时,你也存在资源浪费,因为你的CPU可能空闲,而磁盘非常忙。这也是dump存在的意义。
第二个问题上面已经解释一些了,但,你可能付出更多的代价,因为持久化你也可能不够满意,你可能需要寄送日志系统,寄送Hadoop存储,写数据库等等,为此,可能非常慢

在了解以上以后,你可以尝试看看负载是否能满足你的要求,比如你有几百个库存,那这样可能已经满足你了,1秒内就以非常小的并发就秒完了,之后的只要拒绝就行了

如果是几万的,要在一秒内,就比较狗血了,为此你可能为此在进入这个单点之前就要设置拒绝率,也就是某些人可能是在这个时序之前就秒杀到了,但你却要拒绝他。但用户很难发现,因为这当中涉及的系统非常多,有个几百毫秒的延时也很正常。

如果是几百万库存的(我不知道是否存在这样的场景),那你必须分布式来解决,找很多个单点以一种哈希形式来分布。为此,你可能存在一个单点没秒完,另外一个早就结束的哈希不均匀情况,这种场景非常常见,原因是你无法预测用户,而哈希方法是事先决定的。

这就凭经验了,我想做过很多次以后,应该能找到一个相对均匀的方法来分布你的秒杀需求。 本人没有接触过taobao秒杀系统的开发,所以是从不同角度来回答这个问题,仅作参考。
这类问题最开始应该先定好量级,不同量级的系统设计是完全不同的。
拿taobao举例,他们的秒杀系统肯定是世界独一无二的,在双十一零点,几亿用户开始刷新页面和App,对于Web服务和API服务的压力可想而知。
我将秒杀的预期降低,降低到我遇见过的量级,比如,一分钟内100万用户开始秒杀,这时系统如何处理。

我们再来看业务,秒杀业务特点是什么?我觉得有以下几点:
1,这个是用户需要购买/下单的,所以,如果我获得了资格,一定是有货物,我是可以支付的。相反,如果我看到了自己没拍到,也没所谓,因为抢不到很正常么。
2,用户一定是在特定时间点附近疯狂刷新的。
3,峰值数据流量巨大,这就是人肉DDOS攻击(肯定也有机器DDOS攻击的元素在里面)

对于这几类业务特点,逐一分析:
1.1,一百万用户,可能会购买上千万件物品(产生千万级的交易)。当用户取得资格后,服务器需要去处理这块交易。这里的行为时间点分布已经可以近似于正态,因为获取资格后,支付之类的行为会规定在一段时间内,比如15分钟内付款,或者当天付款。这种业务量一定是分布式交易系统才可以支撑,其中分布式消息队列、水平分割、多层负载均衡和多层缓存是一定会有的。至于技术选型、各家有各家的方法,这里不做过多的讨论,因为到这一层,从交易数量和频率上来看是正常水品中的了。
1.2,对于用户获取购买资格这块业务,就需要单独拆分出来,因为即使是一百万用户,在同一时间同时抢千万件商品,产生的请求可能是几亿的量级,考虑到这些请求可能出现在几秒钟内,几乎没有任何动态系统能够支撑。即使我先做了3/4层负载均衡,再去dns轮训,再去用一千台nginx分流到业务服务器,每个业务群组有100台服务器,每台服务器要处理的并发数量也是在1000transaction/second以上。这只是我yy出来的结果,前几年貌似听过fb/google之类的主要业务支撑服务器也就是在2k~5k台之间,至于这种1000x100=10w太服务器的量级,估计也没有负载均衡设备来支撑。So, 这里尽量降低动态数据对业务的影响,比如我们将商品抢购结果生成token队列,拿到中签token的用户才有资格去购买,这些token全部是静态数据,按队列形式获取。不同地理位置,安排不同的队列,提前分配好量,最终请求都不要落入交易的业务系统中。
2,对于用户疯狂刷新的行为,这里业务的量级是前面获取资格业务的至少10倍,也就是会产生几十亿次请求。两点应对策略:每次http请求url都不是相同的,也是token的机制,连接不能反复使用,这样防止了人肉/机器ddos的可能性。二是静态资源cdn,这样节约了主营业务的带宽。
3,对于流量问题,第二点中说的cdn外,前端js脚本以及app端的逻辑尽量能够引流。比如我手机不停刷刷刷,app在时间到达之前,或者http协议缓存过期前都返回本地缓存即可,cdn的流量都不需要。

总的来说:
app/html->cdn/各层负载均衡->业务拆分->数据拆分+异步处理/修复

来解决特定的业务需求。对于秒杀来说,业务拆分很重要,对于不可能完成的并发要求,讨巧的去静态化了而已。在我的认知里,支撑百万用户量级的解决方案就是这样的。对于taobao这类高3~4个数量级的业务需求,除了优化每个环节的服务能力,不同的业务解决方案也是必须的

人气教程排行