《大型网站技术架构》读书笔记——第1篇 概述

1. 大型网站架构演化

1.1 大型网站软件系统的特点

  • 高并发、大流量
  • 高可用
  • 海量数据
  • 用户分布广泛,网络情况复杂
  • 安全环境恶劣
  • 需求快速变更,发布频繁
  • 渐进式发展

1.2 大型网站架构演化发展历程

  1. 初始阶段,应用程序、数据库、文件等资源都在同一台服务器上,通常是LPAM(Linux,PHP,Apache,MySQL)。


  1. 应用服务和数据服务分离,随着业务的发展一台服务器已经不能满足需求了,这时候就将数据服务分离出来了。


  1. 使用缓存改善网站性能,通常网站的访问遵循二八定律,大部分的业务访问集中在小部分数据上,那么缓存这部分数据就可以减轻服务器的压力,从而提高访问速度。缓存分为两种:本地缓存和远程分布式缓存。


  1. 使用应用服务器集群改善网站的并发处理能力,应用服务器利用集群来实现网站的可伸缩性,一般通过负载均衡调度服务器来将集群中加入更多的应用服务器。



  2. 数据库的读写分离,使用缓存并不能满足更多的用户规模,数据库会因为负载过大成为网站性能的瓶颈。目前主流的数据库都提供主从热备功能,通过主从复制来实现数据库的读写分离。



  3. 使用反向代理和CDN加速网站响应,反向代理和CDN的原理都是缓存,区别在于CDN部署在网络提供商的机房,根据地理位置来获取数据;而反向代理则部署在网站的中心机房,当请求达到中心机房的时候首先访问反向代理。



  1. 使用分布式文件系统和分布式数据系统,随着业务需求的持续增长,文件系统也不能满足需求了。分布式数据库是网站数据库拆分的最后手段,只能有不得已的情况下,才将大表拆分,通常的手段是业务分库,即将不同业务的数据部署在不同的物理机上。



  2. 使用NoSQL和搜索引擎,对于数据存储和检索的需求越发复杂,NoSQL和搜索引擎有着更好的可伸缩的分布式特性。



  3. 业务拆分,对了应对日益复杂的业务场景,通过分而治之的手段,将整个网站业务拆分成不同的产品线,分别由不同的业务团队负责。应用之间可以通过一个超链接建立关系,还可以使用消息队列进行数据分发,最多的是通过访问同一个数据存储系统来构成一个关联的完整系统。



  4. 分布式服务,随着业务拆分越来越小,部署维护难度增大。既然每一个应用系统都需要执行许多相同的操作,那么可以将这些共有的业务提取出来,独立部署。



2. 大型网站架构模式

模式,来自建筑学的定义“每一个模式描述了一个在我们周围不断重复发生的问题及该问题解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复工作”。关键在于问题和场景的可重复性带来的解决方案的可重复性

2.1 网站架构模式

  • 分层:通过分层,可以将一个庞大的系统分成不同的部分,便于分工合作与维护;各层之间具有一定的独立性,只要维护调用接口不变,各层可以根据具体问题具体分析。分层通常都是逻辑上的,部署上可以在同一台物理机上也可以分离部署。
  • 分割:分割是对软件的纵向切分,将不同的功能和服务分割开,有助于开发和维护也提高了网站的并发处理能力和功能拓展性。例如,在应用层对不同业务进行分割,分成购物、论坛、搜索、广告等。
  • 分布式:分层和分割都是为了方便分布式部署,即将不同模块部署在不同的服务器上,通过远程调用协作。分布式同样带来一些问题,网络对于性能的影响,服务器宕机的威胁,数据一致性等问题。常用的分布式方案有:
    • 分布式应用和服务:将分层和分割后的应用按照模块分布式部署;
    • 分布式静态资源:动静分离的策略,减轻服务器负载和加快加载速度;
    • 分布式数据和存储:海量数据,单个机器已经无法存储,只有利用分布式存储;
    • 分布式计算:加快数据处理的速度
  • 集群:多台服务器部署相同应用构成一个集群,通过负载均衡设备共同对外提供服务;
  • 缓存:将数据存放在距离计算最近的位置以加快处理速度,缓存是改善软件性能的第一手段。
    • CDN:内容分发网络,部署在距离客户端最近的网络服务商,用户的网络请求总是先到达他的网络服务商那里,在这里缓存网站的一些静态资源。
    • 反向代理:属于网站前端架构的一部分,部署在网站的前端,当用户请求达到网络的数据中心的时候,最先访问反向代理,这里会缓存网站的静态资源。
    • 本地缓存:应用服务器本地缓存着一些热点数据,直接可以在本机内存中访问数据,无需访问数据库。
    • 分布式缓存:缓存所需的空间太大,单机不能承受,会存放在一个专门的分布式缓存集群。
  • 异步:通过异步来给系统解耦,异步构架是典型的生产者-消费者模式。
  • 冗余:为了应对服务器的宕机,应当保持服务器的一定冗余,实现高可用。数据库利用定期备份存档,实现冷备份;利用主从分离,实现热备份
  • 自动化:目前主要集中在发布运维方面
  • 安全:通过密码和手机验证码进行身份认证;登录、交易等操作需要对网络通信进行加密;为了防止机器人程序滥用网络资源攻击网站,使用验证码识别;对于XSS攻击、SQL注入等常见攻击进行相应处理;对交易转账等重要操作根据交易模式和交易信息进行风险控制。

3. 大型网站核心架构要素

架构,即“最高层次的规划,难以改变的决定”

软件架构,即“有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计”。系统的各个重要部分及其关系构成了系统的架构,这些组成部分可以是具体的功能模块,也可以是非功能的设计与决策,它们相关的关系组成一个整体,共同构成了软件系统的架构。

系统架构需要关注性能、可用性、伸缩性、扩展性和安全性这5个架构要素来衡量一个软件架构设计的优劣。

3.1 性能

优化网站性能的手段非常多,从用户浏览器到数据库,影响用户请求的所有环节都可以进行性能优化。

在浏览器端,可以通过浏览器缓存、使用页面压缩、合理布局页面、减少Cookie传输等改善性能。

在应用服务器端,可以使用服务器本地缓存和分布式缓存,通过缓存在内存中的热点数据处理用户请求,加快请求处理过程,降低数据库负载。

可使用CDN,将网站静态内容分发到离用户最近的网络服务商机房;在网站机房部署反向代理服务器,缓存热点数据,加快请求响应速度,减轻数据库压力。

可通过异步操作将用户请求发送至消息队列后直接返回响应给用户。

可以将多台应用服务器组成一个集群共同对外服务,提高整体处理能力,优化性能。

在代码层面,使用多线程、改善内存管理等手段优化性能。

在数据库上,使用索引、缓存、SQL优化等改善性能。

衡量性能有一系列指标,重要的有响应时间、TPS、系统性能计数器等。

3.2 可用性

高可用设计的目标是当服务器宕机的时候,服务或者应用依然可用。

主要手段是冗余,对于应用服务器来说,任何一台机器宕机,通过负载均衡都可以将请求切换到其他服务器上实现高可用,前提条件是在应用服务器上不能保存请求的会话信息。

对于存储服务器来说,需要对数据进行实时备份,当服务器宕机的时候切换服务器进行数据恢复可以保证宕机时候的数据依然可用。

网站的高可用还需要软件开发过程的质量保证。通过预发布验证、自动化测试、自动化发布、灰度发布等手段,减少将故障引入线上环境的可能。

衡量高可用的标准是,假设系统中任何一台或多台服务器宕机以及各种不可预期的问题的时候,系统整体是否依然可用。

3.3 伸缩性

伸缩性,即通过不断向集群加入服务器的手段来环节不断上身用户并发访问压力和不断增长的数据存储需求。

对于应用服务器集群,只要服务器上不保存数据,所以服务器都是对等的,通过使用合适的负载均衡设备就可以向集群中不断加入服务器。

对于缓存服务器集群,加入新的服务器可能会导致缓存路由失效,进而导致集群中大部分缓存数据都无法访问。需要改进缓存路由算法来保证缓存数据的可访问性。

关系型数据难以做到大规模集群的可伸缩性,一般通过路由分区等手段将部署有多个数据库的服务器组成一个集群。

3.4 扩展性

扩展性是直接关注网站的功能需求,主要标准是在网站增加新的业务产品时,是否可以实现对现有产品透明无影响,不需要任何改动或者很少改动既有业务功能就可以上线新产品。

主要手段是事件驱动构架和分布式服务。事件驱动架构通常由消息队列实现,将用户和其他业务事件造成的消息发布到消息队列,消息的处理者作为消费者从消息队列中获取消息进行处理。通过这种方式将消息的产生和处理分离,可以透明地增加新消息的生产者或者新消息的消费者。

分布式服务则是由将业务和可复用服务分离开,通过分布式服务框架调用。新增产品可以通过调用复用的服务实现自身的业务逻辑;可复用服务升级变更后,也可以通过提供多版本服务对应用实现透明升级。

通常大型网站会吸引第三方开发者,调用网站服务,其主要途径就是大型网站提供的开放平台接口。

3.5 安全性

安全性,即保护网站不受恶意访问和攻击,保护网站的重要数据不被窃取。

其衡量标准就是针对现存和潜在的各种攻击与窃密手段,是否有可靠的应对策略。

001职业的天花板来自认识的局限性

职业的天花板来自认识的局限性

计算机思维

计算机思维是全方位的,不太可能用一两句来概括。简单地讲,需要处理好这样七对关系:

  1. 大和小

    生活在今天的人依然对于大数的认知是无感的。换一个角度这也说明了人对于“大”和“小”这两个概念的理解其实受限于具体生活的环境。你习惯了某一个环境的度量,其实很难理解在量级上大得多的世界。

  2. 快和慢

    人的进化相对于计算机的发展就是很慢的,计算机的发展遵循“摩尔定律”,在智能时代,人的思维要适应这种快速变化。

  3. 多维度和单一维度

    从总体上看,人脑是线性处理事务的,看问题常常是一个角度,也没有能力把很多角度综合起来。但是,计算机有这个能力,因此占到了多维度的便宜。

  1. 网络和个体

    人的思维的个体行为,作决定彼此不干扰。这有好的一面,但是也难以集中很多人的智慧,产生叠加的效果。事实上,群体智慧的简单叠加甚至不如个人智慧。但是人工智能是建立在网络效应基础上的,它是通过很多彼此联系的计算机共同协作工作而产生的。

  2. 自顶向下和自底向上

    自顶向下做事这一点是计算机的精髓,而人更适应自底向上。在一个组织内,自底向上的做事方式更加容易激发群体的积极性,但是容易造成资源的浪费。

  3. 全局和局部

    人做事情时,限于自己的认知,通常得到的是局部最佳,失去对全局的优化的可能性。由于计算机有处理大数的能力,以及是自顶向下的做事方式,更加容易得到全局最优。

  4. 成本和表现

    人很多时候喜欢强调对错,喜欢追求绝对的公平,喜欢要求最好的结果。但是,从工程的角度讲,好和坏,只是在固定成本下相对的表现。计算机里面无论是软件设计,还是硬件设计,都是平衡性能和成本的关系。

此外,掌握计算机思维,还需要理解下面两个原则:

一. 等价性原则

很多时候,一个较难的问题A和相对容易的问题B是等价的。但是人类常常容易给什么问题就解决什么问题,给了A就解决A,尽管它很难。而计算机则会试图解决等价,但是却更简单的问题。

二.模块化原则

我们在生活中,做一个桌子,或者一个椅子,会直接去做。而在计算机的世界里,永远是先制作几个非常简单,能够大量复制的乐高积木块,然后用很多这样简单的模块,搭出复杂的桌子和椅子。

计算机思维的一个方面就是对“大”和“小”的理解,或者说是对量级这个概念的认识。

我们人类生活的环境,决定了我们对于大数字其实是无感的。也就是说,我们的生活环境限制了我们的认知。例如:会做PPT的人会用图表来展示数字而不是用数字的列表;还有王健林“小目标”的一个亿。

生活在今天的人依然对于大数的认知是无感的。换一个角度这也说明了人对于“大”和“小”这两个概念的理解其实受限于具体生活的环境。你习惯了某一个环境的度量,其实很难理解在量级上大得多的世界。

今天人的思维当然比一万年前的酋长们开阔许多,但是相比计算机的思维还是显得落户了很多,因为计算机自诞生就是针对大数设计的

由于一开始就是针对海量数字设计的,因此计算机思维和人的思维就是不同的。例如,对于围棋的变化数量是数不清的,因为这个数字太大了。简单地进行数学分析一下,棋盘上每一个点最终可以的黑子、白子或者空位三种情况,棋盘一共有361个交叉点,因此最多可以有3^361(约为2*10^172)种情况。对于这么大的数字,人类对于它是无感的。

因此,这么多变化对于人类来说就是无穷无尽的。于是乎,我们人类就不把下围棋当作一种计算问题,而是把这件事情当成一种文化,称为“棋道”。

相比计算机,人类对数字的认知也受限于我们作为生物进化的速度,这是人的思维和计算机思维的另外一个不同之处。

人类进步的速度相对于计算机的进步速度就显得非常慢了,摩尔定律让计算机每十八个月性能翻一番,这相当于大约每五年涨十倍,或者每十年进步一百倍!

很多IT从业者的思维方式并没有跟上这个时代,这是他们很难在这个行业里突破天花板的根本原因。

重点总结

很多人和企业缺失了一种信息时代的思维方式,我们把它称为“计算机思维”。这并不是说计算机有思维,而是因为这种思维方式是伴随着计算机出现的。

在后信息时代,或者是即将进入智能时代,所有人都需要升级自己的思维方式,让自己的思维方式跟上这个时代。只有这样,才能不断突破职业发展的天花板。

003为什么计算机不是万能的

为什么计算机不是万能的

从计算的本质来看看计算机的极限,这些思考方式来自于图灵博士。

在20世纪30年代中期,图灵思考的三个问题:

  1. 世界上是否所有数学问题都有明确的答案?

  2. 如果有明确的答案,是否可以通过有限步骤的计算得到答案?

  3. 对于那些有可能在有限步骤计算出来的数学问题,能否有一种假想的机械,让它不断运动,最后当机器停下来的时候,那个数学问题就解决了?

像图灵这样超越时代的人,他不是在跟在蚂蚁后面来观察一件事情发展的规律,而是在前面等着大家,找到极限所在,然后他告诉大家,就在极限里寻找具体问题的答案吧,不要浪费时间纠结没有意义的事情,也就是那些试图超越极限的事情。

今天所有的计算机,包括全世界正在设计的新的计算机,从解决问题的能力来讲,都没有超出图灵机的范畴。图灵,其实为今天的计算机和很长时间以后的未来计算机所能解决的问题划了一道不可超越的边界。

人工智能的边界

  1. 世界上很多问题,其中只有一小部分是数学问题;
  2. 在数学问题中,只有一小部分是有解的;
  3. 在有解的问题中,只有一部分是理想状态的图灵机可以解决的;
  4. 在后一类的问题中,又只有一部分是今天实际的计算机可以解决的;
  5. 而人工智能可以解决的问题,又只是计算机可以解决问题的一部分。

图灵受到了另一位数学大师希尔伯特的启发。希尔伯特在1900年的巴黎国际数学家大会上,提出了23个重要的、根本性的数学问题(也被称为希尔伯特问题)。

其中第十个问题讲的是这样一件事,“随便给一个不确定的方程,能否通过有限步骤的运算,判定它是否存在整数解?”这个答案是否定的,那么就说明很多数学问题其实上帝也不知道答案是否存在。正是希尔伯特的这个提问,让图灵明白了计算机的极限所在。

第二个给予图灵巨大启示的人是他的精神导师冯·诺依曼。图灵在读了他的《量子力学的数学原理》一书后,意识到计算来自于确定性的机械的运动。

至于21世纪的电子计算机,里面电子的运动其实等价于机械运动。图灵同时猜测人的意识来自于测不准原理,这是宇宙本身的规律。图灵从此得出结论,计算的确定的,而意识可以是不定的,两者不可能划等号。

很多人胡思乱想计算机是否有意识,其实早在80年前,图灵就感到两者是两回事,这就是任何计算机的边界。

从图灵的事迹上,我们可以得到是启示是:要和比自己强的人在一起,这一点很重要,因为只有这样我们的认知才能提升。反之,如果总是和臭棋篓子下棋,只能越下越臭。

重点总结

  • 图灵和常人思维的方式的差别在于:图灵是先找到极限所在,然后再极限里寻找具体问题的答案,而不是浪费时间去做那些试图超越极限的事情。
  • 图灵机是一个数学模型,今天所有的计算机,包括正在设计的新的计算机,从从解决问题的能力来讲,都没有超出图灵机的范畴。
  • 人工智能所能解决的问题只是世界上问题的很小一部分。现在世界上没有解决的问题太多,要想办法解决各种问题,而不是杞人忧天,担心人工智能太强大。

000思维方式决定商业模式

思维方式决定商业模式

生活在小数字世界的人,天然地缺乏处理大数字世界里的问题的思维方式,无形之中地将人们限制在天花板之下。

例如:一是超过一百双鞋子的人,都进行了分类管理,如果鞋子再多,简单的分类已经不能解决问题了,必须对鞋子建索引;二是近万册藏书,也需要对书籍建索引,这样在找一本书的时候,先要从索引中找到那本书在第几排书架,第几个架子,第几层,然后再到那一排去找书。

人生活在小数字世界里,难免保留固有的习惯,但是既然从事了计算机这个行业,就需要按照计算机这个行业的规矩来办事,不能先验地假设数值一定不多。

其次,在计算机这个世界里,几乎任何常见的问题都已经有了优化过的答案,作为从业者,首先要擅长使用专业人士给出的,验证了无数次的答案,而不是自己凭着生活经验一拍脑袋地想出一个做法。如果为了赶时间,应该采用现有的,高质量的代码,而不是自己写一个。

因此,IT从业人员遇到职业天花板的第一个原因是一开始思维方式就错了。不克服我们先天认识上的局限性,就无法领会IT这个行业的精髓,当然事业也就做不上去。这样的道理同样适应于企业,例如曾经辉煌过的雅虎公司和中国几大门户网站今天遇到的困境,就植根于此。

在互联网2.0时代之后,,每一个人都能够产生新闻,这时候,新闻多得靠栏目分类已经无法解决了,今日头条不得不靠个性化筛选新闻。新闻门户网站的每况愈下和今日头条的兴起,实际上就是两种思维方式的对决。

可以讲,对数量大小的认知决定了商业模式,也决定了企业的成败。在新时代,更重要和有益的恐怕是在思维上要提升,这样才容易成为新时代前2%的受益者。

重点总结

我们生活在小数字世界,从小数字世界总结出来的方法论无法应用到更高量级的大数世界。

对于企业,提前把自己定义在大数世界里,才能建立更有竞争力的商业模式。

作为个人,必须升级思维方式,才能适应增长迅速的大数世界,成为新时代前2%的受益者。

002工程思维:直觉和极限

工程思维:直觉和极限

结合生活环境,来看看我们的直觉是如何误导我们的,以及工程中“极限”这个概念如何让我们突破认识的限制,比常人更快地看清楚问题的本质。

生活中,直觉和生活常识非常有用,但是有时缺乏知识的直觉会欺骗我们。

例如:分苹果的时候,刮掉里面直径的70%的部分是小于剩余部分的。根据体积的计算,只有刮掉苹果里面直径的80%,里外的重量才大致相当。事实上,如果一个球的直径增大一倍,体积可是大7倍,而不是想象中的两三倍。

又如:Google过去面试产品经理常见的一道面试题——面试的房间里能够装下多少个高尔夫球?

胡猜对于这道题是不行的!简单分析一下,高尔夫球大约直径4厘米,如果我们把它们整整齐齐地像立方体那样码在一起,用眼睛估摸着房间的面积和高度,用小学数学就能够解决。例如一个面积15平方,高3米的小会议室,大约可以装70万个(10,000*70)。Google考察这一题的目的是:要求产品经理在没有数据之前不要轻易给出结论。遵循一套工程思维解决问题的人,对这个问题估计出来的大致数量级不大会出错。

在上面一类问题中,更正错误的直觉并不难,但是在有些事情上要我们放弃掉我们从生活中获得的直觉,则是千难万难。

例如,在高速行进的火车上分别往前面和后面各打一束光,哪束光的速度快?按照我们的直觉,或者说低俗世界的经验,一定是往前打的光更快,因为速度是叠加的。但是,爱因斯坦的相对论告诉我们,它们是一样快的,因为光速是一个常数,产生不了叠加的效果。

极限对于工程师来讲是一个非常重要的概念。任何产品的性能都有一个物理上无法突破的极限,这个极限早就通过已有的理论直接给出。

重点总结

直觉很容易误导人,掌握工程中的“极限”概念可以让我们突破认识的限制,比常人更快地看清楚问题的本质。

所谓掌握工程思维的技巧,就是要比生活超越一个层级。这就如同你看蚂蚁的爬行轨迹时,不能跟在它的后面,而要从它的上方看。