你好,我是许令波,花名“君山”。说起来我的职业生涯算是比较简单,2009年大学毕业后就进入了淘宝,一直工作了七年多。这七年多的时间里,我有幸看到了淘宝业务的快速增长,并且以开发者的身份参与其中。
说实话,作为一名程序员,我的技术能力也在公司业务的快速增长过程中得到了历练,并积累了一些大流量高并发网站架构设计和优化的经验,尤其是针对“秒杀”这个场景。因为我确信,那个时候我们肯定是对系统做了足够多的极致优化,才能扛住当时洪峰般的流量请求。
记得早期的时候,淘宝商品详情系统的PV还差不多是1亿的样子,但是到2016年差不多已经升至50亿了。尤其是2012年到2014年那个时间段,“秒杀”活动特别流行,用户的参与热情一浪高过一浪,系统要面对的流量也是成倍增长。
而每一次的秒杀活动对技术团队来说都是一次考验。现在想起来,那个时候我们整个团队,无所畏惧,逐步迭代创新,然后解决一个个难题的过程,也是极具挑战性和成就感的事情。
记得有一年,为了应对“双十一”,我们整个商品详情团队对系统做了很多优化,我们自认为已经是整个公司最牛的系统了,性能也已经是“业界之巅”。
但是那年“双十一”的晚上,我们的系统还是遇到了瓶颈。当时老大就跑过来盯着我们,问我们什么时候能够恢复,我们整个团队都承担着巨大的心理压力。
事后我们复盘宕机的原因,发现当时的秒杀流量远远超过了我们的预想,我们根本没想到大家的参与热情能有那么高。于是我们按照这个增长率去预估下一年的流量和服务器,粗算下来,我记得差不多要增加2000台服务器,简直不可思议。
怎么可能真正增加这么多机器,所以这也就倒逼我们必须找出一些特殊的手段来优化系统。后面,经过一段时间的调研和分析,我们想到了把整个系统进行动静分离改造的解决方案。
秒杀系统也差不多那个时候才从商品详情系统独立出来成为一个独立产品的。因为我见证了秒杀系统的建设过程,所以也有颇多感慨。秒杀系统的迭代又是一个升级打怪的过程,我们也都是遇到问题解决问题,逐一优化。
那么,如何才能更好地理解秒杀系统呢?我觉得作为一个程序员,你首先需要从高维度出发,从整体上思考问题。在我看来,秒杀其实主要解决两个问题,一个是并发读,一个是并发写。并发读的核心优化理念是尽量减少用户到服务端来“读”数据,或者让他们读更少的数据;并发写的处理原则也一样,它要求我们在数据库层面独立出来一个库,做特殊的处理。另外,我们还要针对秒杀系统做一些保护,针对意料之外的情况设计兜底方案,以防止最坏的情况发生。
而从一个架构师的角度来看,要想打造并维护一个超大流量并发读写、高性能、高可用的系统,在整个用户请求路径上从浏览器到服务端我们要遵循几个原则,就是要保证用户请求的数据尽量少、请求数尽量少、路径尽量短、依赖尽量少,并且不要有单点。这些关键点我会在后面的文章里重点讲解。
其实,秒杀的整体架构可以概括为“稳、准、快”几个关键字。
所谓“稳”,就是整个系统架构要满足高可用,流量符合预期时肯定要稳定,就是超出预期时也同样不能掉链子,你要保证秒杀活动顺利完成,即秒杀商品顺利地卖出去,这个是最基本的前提。
然后就是“准”,就是秒杀10台iPhone,那就只能成交10台,多一台少一台都不行。一旦库存不对,那平台就要承担损失,所以“准”就是要求保证数据的一致性。
最后再看“快”,“快”其实很好理解,它就是说系统的性能要足够高,否则你怎么支撑这么大的流量呢?不光是服务端要做极致的性能优化,而且在整个请求链路上都要做协同的优化,每个地方快一点,整个系统就完美了。
所以从技术角度上看“稳、准、快”,就对应了我们架构上的高可用、一致性和高性能的要求,我们的专栏也将主要围绕这几个方面来展开,具体如下。
- 高性能。 秒杀涉及大量的并发读和并发写,因此支持高并发访问这点非常关键。本专栏将从设计数据的动静分离方案、热点的发现与隔离、请求的削峰与分层过滤、服务端的极致优化这4个方面重点介绍。
- 一致性。 秒杀中商品减库存的实现方式同样关键。可想而知,有限数量的商品在同一时刻被很多倍的请求同时来减库存,减库存又分为“拍下减库存”“付款减库存”以及预扣等几种,在大并发更新的过程中都要保证数据的准确性,其难度可想而知。因此,我将用一篇文章来专门讲解如何设计秒杀减库存方案。
- 高可用。 虽然我介绍了很多极致的优化思路,但现实中总难免出现一些我们考虑不到的情况,所以要保证系统的高可用和正确性,我们还要设计一个PlanB来兜底,以便在最坏情况发生时仍然能够从容应对。专栏的最后,我将带你思考可以从哪些环节来设计兜底方案。
最后,很幸运能在极客时间遇到你,希望这堂课能让你彻底理解大并发、高性能、高可用秒杀系统的设计之道,并能够在思考解决类似问题时有更准确的思考和判断。
精选留言
2018-09-26 08:13:55
2018-09-27 10:30:09
2018-09-27 01:17:33
1. 前端限流,5 秒内只提交一个请求,静态资源存放于 CDN。
2. 后端 redis 对 uid 限流,同样 5 秒内提交一个请求。
3. 请求保存队列,队列长度为库存 2 倍。为什么是 2 倍呢?拍脑门决定的,防止前面预订失败,后面补上。
4. 队列满后,后续请求直接返回秒杀结束。
5. 消费线程消费队列内容,下订单,直接操作 MySQL 扣库存。
可惜的是用户量不大,没能很好检验这个系统,因此不了解系统存在哪些问题。
当时也没想到支付超时后,剩余的库存如何处理,导致最后剩余商品没卖出去,囧…
2018-09-28 09:39:55
2018-09-26 08:04:21
2018-09-26 00:50:44
2018-10-23 09:04:01
2018-09-25 23:51:31
2018-09-25 18:57:01
2018-09-29 08:02:23
2018-09-26 07:16:51
2018-09-25 21:24:44
2018-09-25 19:12:12
2018-09-29 21:27:30
2018-09-25 21:33:46
2020-11-19 22:05:06
秒杀系统要解决并发读和并发写两个问题,要达到稳、准、快的要求,这几个关键点总结的很好,期待之后的讲解。
其实这种 7 天的小课,形式挺好的,适合周末或者假期学习,学习下来应该也不累,后来似乎没有了。
2018-09-28 00:13:21
2018-09-25 23:49:03
2018-10-09 18:45:29
2018-09-29 15:50:48