09 架构设计原则案例
周二,我给你介绍了架构设计的三条核心原则,先复习一下:合适原则、简单原则和演化原则。我们在架构设计实践中,应该时刻谨记这三条设计原则,指导我们设计出合适的架构,即使是代表中国互联网技术最顶尖水平的BAT,其架构的发展历程也同样遵循这三条原则。
今天我就以大家耳熟能详的淘宝和手机QQ作为案例,来简单分析一下。
淘宝
注:以下部分内容摘自《淘宝技术发展》。
淘宝技术发展主要经历了“个人网站”→“Oracle/支付宝/旺旺”→“Java时代1.0”→“Java时代2.0”→“Java时代3.0”→“分布式时代”。我们看看每个阶段的主要驱动力是什么。
1.个人网站
2003年4月7日马云提出成立淘宝,2003年5月10日淘宝就上线了,中间只有1个月,怎么办?淘宝的答案就是:买一个。
估计大部分人很难想象如今技术牛气冲天的阿里最初的淘宝竟然是买来的,我们看看当初决策的依据:
当时对整个项目组来说压力最大的就是时间,怎么在最短的时间内把一个从来就没有的网站从零开始建立起来?了解淘宝历史的人知道淘宝是在 2003 年 5 月 10 日上线的,这之间只有一个月。要是你在这个团队里,你怎么做?我们的答案就是:买一个来。
淘宝当时在初创时,没有过多考虑技术是否优越、性能是否海量以及稳定性如何,主要的考虑因素就是:快!
因为此时业务要求快速上线,时间不等人,等你花几个月甚至十几个月搞出一个强大的系统出来,可能市场机会就没有了,黄花菜都凉了。
同样,在考虑如何买的时候,淘宝的决策依据主要也是“快”。
买一个网站显然比做一个网站要省事一些,但是他们的梦想可不是做一个小网站而已,要做大,就不是随便买个就行的,要有比较低的维护成本,要能够方便地扩展和二次开发。
那接下来就是第二个问题:买一个什么样的网站?答案是:轻量一点的,简单一点的。
买一个系统是为了“快速可用”,而买一个轻量级的系统是为了“快速开发”。因为系统上线后肯定有大量的需求需要做,这时能够快速开发就非常重要。
从这个实例我们可以看到:淘宝最开始的时候业务要求就是“快”,因此反过来要求技术同样要“快”,业务决定技术,这里架构设计和选择主要遵循的是“合适原则”和“简单原则”。
第一代的技术架构如图所示。
2.Oracle/支付宝/旺旺
淘宝网推出后,由于正好碰到“非典”,网购很火爆,加上采取了成功的市场运作,流量和交易量迅速上涨,业务发展很快,在2003年底,MySQL已经撑不住了。
一般人或者团队在这个时候,可能就开始优化系统、优化架构、分拆业务了,因为这些是大家耳熟能详也很拿手的动作。那我们来看看淘宝这个时候怎么采取的措施:
技术的替代方案非常简单,就是换成Oracle。换Oracle的原因除了它容量大、稳定、安全、性能高,还有人才方面的原因。
可以看出这个时候淘宝的策略主要还是“买”,买更高配置的Oracle,这个是当时情况下最快的方法。
除了购买Oracle,后来为了优化,又买了更强大的存储:
后来数据量变大了,本地存储不行了。买了NAS(Network Attached Storage,网络附属存储),NetApp的NAS存储作为了数据库的存储设备,加上Oracle RAC(Real Application Clusters,实时应用集群)来实现负载均衡。
为什么淘宝在这个时候继续采取“买”的方式来快速解决问题呢?我们可以从时间上看出端倪:此时离刚上线才半年不到,业务飞速发展,最快的方式支撑业务的发展还是去买。如果说第一阶段买的是“方案”,这个阶段买的就是“性能”,这里架构设计和选择主要遵循的还是“合适原则”和“简单原则”。
换上Oracle和昂贵的存储后,第二代架构如图所示。
3.脱胎换骨的Java时代1.0
淘宝切换到Java的原因很有趣,主要因为找了一个PHP的开源连接池SQL Relay连接到Oracle,而这个代理经常死锁,死锁了就必须重启,而数据库又必须用Oracle,于是决定换个开发语言。最后淘宝挑选了Java,而且当时挑选Java,也是请Sun公司的人,这帮人很厉害,先是将淘宝网站从PHP热切换到了Java,后来又做了支付宝。
这次切换的最主要原因是因为技术影响了业务的发展,频繁的死锁和重启对用户业务产生了严重的影响,从业务的角度来看这是不得不解决的技术问题。
但这次淘宝为什么没有去“买”呢?我们看最初选择SQL Relay的原因:
但对于PHP语言来说,它是放在Apache上的,每一个请求都会对数据库产生一个连接,它没有连接池这种功能(Java语言有Servlet容器,可以存放连接池)。那如何是好呢?这帮人打探到eBay在PHP下面用了一个连接池的工具,是BEA卖给他们的。我们知道BEA的东西都很贵,我们买不起,于是多隆在网上寻寻觅觅,找到一个开源的连接池代理服务SQL Relay。
不清楚当时到底有多贵,Oracle都可以买,连接池买不起 ?所以我个人感觉这次切换语言,更多是为以后业务发展做铺垫,毕竟当时PHP语言远远没有Java那么火、那么好招人。淘宝选择Java语言的理由可以从侧面验证这点:
Java是当时最成熟的网站开发语言,它有比较良好的企业开发框架,被世界上主流的大规模网站普遍采用,另外有Java开发经验的人才也比较多,后续维护成本会比较低。
综合来看,这次架构的变化没有再简单通过“买”来解决,而是通过重构来解决,架构设计和选择遵循了“演化原则”。
从PHP改为Java后,第三代技术架构如图所示。
4.坚若磐石的Java时代2.0
Java时代2.0,淘宝做了很多优化工作:数据分库、放弃EJB、引入Spring、加入缓存、加入CDN、采用开源的JBoss。为什么在这个时候要做这些动作?原文作者很好地概括了做这些动作的原因:
这些杂七杂八的修改,我们对数据分库、放弃EJB、引入Spring、加入缓存、加入CDN、采用开源的JBoss,看起来没有章法可循,其实都是围绕着提高容量、提高性能、节约成本来做的。
我们思考一下,为什么在前面的阶段,淘宝考虑的都是“快”,而现在开始考虑“容量、性能、成本”了呢?而且为什么这个时候不采取“买”的方式来解决容量、性能、成本问题呢?
简单来说,就是“买”也搞不定了,此时的业务发展情况是这样的:
随着数据量的继续增长,到了2005年,商品数有1663万,PV有8931万,注册会员有1390万,这给数据和存储带来的压力依然很大,数据量大,性能就慢。
原有的方案存在固有缺陷,随着业务的发展,已经不是靠“买”就能够解决问题了,此时必须从整个架构上去进行调整和优化。比如说Oracle再强大,在做like类搜索的时候,也不可能做到纯粹的搜索系统如Solr、Sphinx等的性能,因为这是机制决定的。
另外,随着规模的增大,纯粹靠买的一个典型问题开始成为重要的考虑因素,那就是成本。当买一台两台Oracle的时候,可能对成本并不怎么关心,但如果要买100台Oracle,成本就是一个关键因素了。这就是“量变带来质变”的一个典型案例,业务和系统发生质变后,架构设计遵循“演化原则”的思想,需要再一次重构甚至重写。
Java架构经过各种优化,第四代技术架构如图所示。
5.Java 时代3.0和分布式时代
Java时代3.0我个人认为是淘宝技术飞跃的开始,简单来说就是淘宝技术从商用转为“自研”,典型的就是去IOE化。
分布式时代我认为是淘宝技术的修炼成功,到了这个阶段,自研技术已经自成一派,除了支撑本身的海量业务,也开始影响整个互联网的技术发展。
到了这个阶段,业务规模急剧上升后,原来并不是主要复杂度的IOE成本开始成为了主要的问题,因此通过自研系统来降低IOE的成本,去IOE也是系统架构的再一次演化。
手机QQ
注:以下部分内容摘自《QQ 1.4亿在线背后的故事》。
手机QQ的发展历程按照用户规模可以粗略划分为4个阶段:十万级、百万级、千万级、亿级,不同的用户规模,IM后台的架构也不同,而且基本上都是用户规模先上去,然后产生各种问题,倒逼技术架构升级。
1.十万级IM 1.X
最开始的手机QQ后台是这样的,可以说是简单得不能再简单、普通得不能再普通的一个架构了,因为当时业务刚开始,架构设计遵循的是“合适原则”和“简单原则”。
2.百万级IM 2.X
随着业务发展到2001年,QQ同时在线人数也突破了一百万。第一代架构很简单,明显不可能支撑百万级的用户规模,主要的问题有:
- 以接入服务器的内存为例,单个在线用户的存储量约为2KB,索引和在线状态为50字节,好友表400个好友 × 5字节/好友 = 2000字节,大致来说,2GB内存只能支持一百万在线用户。
- CPU/网卡包量和流量/交换机流量等瓶颈。
- 单台服务器支撑不下所有在线用户/注册用户。
于是针对这些问题做架构改造,按照“演化原则”的指导进行了重构,重构的方案相比现在来说也还是简单得多,因此当时做架构设计时也遵循了“合适原则”和“简单原则”。IM 2.X的最终架构如图所示。
3.千万级IM 3.X
业务发展到2005年,QQ同时在线人数突破了一千万。第二代架构支撑百万级用户是没问题的,但支撑千万级用户又会产生新问题,表现有:
- 同步流量太大,状态同步服务器遇到单机瓶颈。
- 所有在线用户的在线状态信息量太大,单台接入服务器存不下,如果在线数进一步增加,甚至单台状态同步服务器也存不下。
- 单台状态同步服务器支撑不下所有在线用户。
- 单台接入服务器支撑不下所有在线用户的在线状态信息。
针对这些问题,架构需要继续改造升级,再一次“演化”。IM 3.X的最终架构如下图,可以看到这次的方案相比之前的方案来说并不简单了,这是业务特性决定的。
4.亿级IM 4.X
业务发展到2010年3月,QQ同时在线人数过亿。第三代架构此时也不适应了,主要问题有:
- 灵活性很差,比如“昵称”长度增加一半,需要两个月;增加“故乡”字段,需要两个月;最大好友数从500变成1000,需要三个月。
- 无法支撑某些关键功能,比如好友数上万、隐私权限控制、PC QQ与手机QQ不可互踢、微信与QQ互通、异地容灾。
除了不适应,还有一个更严重的问题:
IM后台从1.0到3.5都是在原来基础上做改造升级的,但是持续打补丁已经难以支撑亿级在线,IM后台4.0必须从头开始,重新设计实现!
这里再次遵循了“演化原则”,决定重新打造一个这么复杂的系统,不得不佩服当时决策人的勇气和魄力!
重新设计的IM 4.0架构如图所示,和之前的架构相比,架构本身都拆分为两个主要的架构:存储架构和通信架构。
- 存储架构
- 通信架构
小结
今天我给你讲了淘宝和手机QQ两个典型互联网业务的架构发展历程,通过这两个案例我们可以看出,即使是现在非常复杂、非常强大的架构,也并不是一开始就进行了复杂设计,而是首先采取了简单的方式(简单原则),满足了当时的业务需要(合适原则),随着业务的发展逐步演化而来的(演化原则)。罗马不是一天建成的,架构也不是一开始就设计成完美的样子,然后可以一劳永逸一直用下去。
这就是今天的全部内容,留一道思考题给你吧。搜索一个互联网大厂(BATJ、TMD等)的架构发展案例,分析一下其发展过程,看看哪些地方体现了这三条架构设计原则。
欢迎把你的答案写到留言区,和我一起讨论。相信经过深度思考的回答,也会让你对知识的理解更加深刻。(编辑乱入:精彩的留言有机会获得丰厚福利哦!)
- 小小笑儿 👍(81) 💬(1)
适合原则,简单原则,演化原则这三个点归纳得很精辟,本次课程也通过实例来讲解了各个原则的使用。但是我还有个小小的疑问,就是在对这些成功项目进行复盘的时候我们可以很清楚的辨别什么时候采用什么原则优先,而如果把我们回到之前选择的时间点上,如何更准确的判断应该采用什么原则呢?
2018-05-18 - 米斯特.杜 👍(43) 💬(2)
探讨个问题,希望可以得到回答。之前看过云栖社区对faceu的cto的采访,他说当时他们上第一版后台系统时就直接选型了阿里云的drds,他自己也不知道用户量会不会上来。他还说如果当时他没选drds方案,到后来用户井喷式增长时系统再做调整估计等不到改好用户就跑光了。所以我的问题是,对于像这种近两年创业的公司可能做出爆款产品时,系统架构方面是否需要向前多考虑一些?
2018-05-17 - 何国平 👍(40) 💬(3)
所以有些公司要求两三年就重构一次
2018-05-18 - 考休 👍(29) 💬(4)
技术的架构有很大一方面也是由于互联网产品的特殊演化导致的,互联网产品讲究小步快跑、快速迭代,尤其是在产品初期,需要依据初始用户的反馈快速优化产品,所以技术上来说产品初期对可扩展性的要求比较高,而到了中后期,由于产品的核心功能开始稳定,但是用户量又达到了一定的量级,这个时候又对系统的高性能、高可用提出来较高的要求。
2019-07-12 - 沐风 👍(28) 💬(4)
能不能讲下关于并发和pv,日活,在线人数的计算方式和关系
2018-05-18 - bigticket 👍(25) 💬(1)
今天看到一条微博,收集了七年前appstore里微信的用户评价,骂声一片,很多是说连不上数据库的问题,而现在用微信已经很少出现bug,感觉非常能体现架构演进的原则,早期用户量少,架构设计主要考虑合适、简单两个原则,当用户量变大引起复杂度提高,从而导致无法正常运行时,倒逼架构进行演进优化。现在能支持的高峰大并发的方案很多,应该算比较成熟了,那下一个能打破现有架构设计的业务需求可能是什么?感觉又回到了要不要预测问题,过度设计的循环中…
2018-05-26 - syhasia 👍(20) 💬(1)
请问老师,多租户(大于1k)场景下,用户读次数远大于写,数据库需要分库分表吗?还是一个库多个schema(一个schema代表一个用户)就够了?
2018-09-05 - Dong Zhang 👍(13) 💬(1)
我是做infra的,企业部分打交道多,主要做设计实施,售前设计接触过一点。前期拼方案的时候,演进原则不好说,简单和适用还是要的吧,为了降低竞标成本。当然最重要的是和客户感情上关系上生意上都谈拢,很多时候标书都可能是抄某个牌子来的。设计实施的时候简单适用还是很重要,演进还真不是特别快,一般能用未来3~5年就好。我在infra看,构架师和客户的沟通、说服、取信非常重要,特别不同部门不同级别;集成商将各种厂商粘合到一起很难,需要的知识很广;构架师对于项目和行业具体情况的经验积累也是很重要。总体来说我觉得构架师的双商都要高,既能搞定人,也要有技术广度和一定深度,还要有丰富的领域和临场经验。
2018-09-08 - 如风 👍(9) 💬(1)
很多跟我们公司类似,公司从创业再到上市,从无到有,再到每天几千万笔的流量都经历过了,开始也是追求快,所有业务公用一个数据库,一出现问题,引发全部拖死,不断优化演进,业务及架构不断分离,很多东西也是买,买云服务,架构不只是简单的一个框架,涉及的东西太广了,从网络服务器,再到应用软件,数据存储等等,需要建立一套可行的运维监控体系...
2018-05-22 - 黄金的太阳 👍(9) 💬(2)
一直追剧追到现在,感觉受益匪浅,也是第一次留言,因本人能力有限,这篇文章中关于架构演进过程中各个环节希望能有更进一步关于架构图的配套说明,例如 1.本次演进改进的点在哪里 2.为什么这样设计就能解决当时的问题 而不是直接一张图,没有任何说明,也许对于架构师大神们是很小白的问题,但咱们的课程是不是要考虑到从0开始学架构的兄弟们呢?一点小建议
2018-05-17 - 孙振超 👍(8) 💬(1)
各个公司的架构都是逐渐演进成当前的样子,在达到同样目的的过程中实现手段确并不完全相同,蚂蚁和阿里都进行了多地多中心部署的架构改造,但二者在诸如配置中心、跨ldc访问管控等方面都不尽相同,即使在蚂蚁内部也出现了后续实现推翻原始规划的情况。在多地多中心部署架构改造完成后,为进一步降低成本,避免大促活动中机器的浪费,又开始了弹性部署的改造,希望能够在大促高峰来临的前几个小时再临时增加服务器,等活动结束服务器就立即回收。等这个搞定,又开始在线离线混布的改造,进一步降低整体成本。 这些改造只所以一个接一个的能够实现,也在于使用的主要中间件和框架都是自研的,知根知底,可以快速迭代修改,如果是使用第三方的或者购买的,一方面可能非常贵,另一方面可能根本不支持,要重新设计改造部署所需的时间要远远大于自研的成本。
2018-06-04 - hater 👍(6) 💬(1)
有些公司要求两三年就重构一次,不一定是公司重视技术,也可能是人有问题。业务量没增加,业务没变化,换个领导就带一批自己人,推翻以前的重构一次,过两年再换一个领导再换一批人,再重来一次,这样的公司也不少
2018-06-15 - 乌云里的黑帆 👍(6) 💬(2)
老师您好,这样的演化过程需要怎样的人力财力呢?我们公司没架构师,没高级工程师,但总监特别中意阿里的一些方案,这个路线可以成功吗?
2018-05-22 - 俊哥 👍(5) 💬(1)
Java 时代 3.0 我个人认为是淘宝技术飞跃的开始,简单来说就是淘宝技术从商用转为“自研”,典型的就是去 IOE 化。 这里说的是IOE指的是啥?
2019-10-23 - one day 👍(4) 💬(1)
在简单,演化,合适三原则之下我们也要考虑当时的技术水平,淘宝开始的技术是没有目前分布式成熟系统的,我们在架构设计时并不一定开始就搭建一个只是简单的系统,因为我们占在时代前进的道路上,原来是复杂的现在反而是简单,原来需要演化许多年的,现在也可能只需几天。根据业务,根据技术,根据人员,根据时间,根据可看到的未来。架构不确定,多思,就让设计的架构多撑几年
2018-05-28