架构师训练营 1 期第 4 周:系统架构 - 总结

用户头像
piercebn
关注
发布于: 2020 年 10 月 12 日

本文针对互联网系统面临的技术挑战,从系统架构演化角度进行分析,描述了随着业务的发展,系统在演化过程中各阶段面临的问题,以及采用的解决方案和手段;最后对维基百科技术架构进行案例分析。

一、互联网系统的技术挑战与方案

互联网系统面临的技术挑战

  • 高并发,大流量

  • Google 日均 PV 数35亿,日均 IP 访问数3亿

  • 微信在线用户数10亿

  • 天猫双十一活动一天交易额3000亿

  • 高可用

  • 系统7*24小时不间断服务

  • 系统升级时用户无感知

  • 海量数据

  • Facebook 每周上传的照片数目接近10亿

  • 百度收录的网页数目有数百亿

  • Google 有近百万台服务器为全球用户提供服务

  • 用户分布广泛,网络情况复杂

  • 建设异地多活的数据中心

  • 安全环境恶劣

  • 由于互联网的开放性,使得互联网站更容易受到攻击

  • 重要网站泄露用户密码,造成用户损失和影响,让普通用户也直面互联网安全问题

  • 需求快速变更,发布频繁

  • 和传统软件的版本发布频率不同,互联网产品为快速适应市场,满足用户需求,其产品发布频率也是极高的。

  • 大型网站的产品可以做到按周发布,中小型网站甚至可以做到按天发布。

  • 渐进式发展

  • 不同于传统软件产品或者企业应用系统,一开始就规划好全部的功能和非功能需求,几 乎所有的大型互联网站都是从一个小网站开始,渐进的发展起来的。



核心挑战是高并发挑战,很多问题都是由高并发引起的

  • 当大量的用户同时访问系统时,这时就构成了高并发的访问压力

  • 大量用户同时提交请求,系统需要对这些用户同时提供服务处理,为每个用户需要创建线程或者进程,每个线程或进程都需要消耗一定的CPU资源,需要占据一定的内存,需要消耗一定的磁盘访问,需要消耗一定的网络带宽空间,当高并发用户同时访问系统时,要想同时服务好用户,系统必须提供足够多的系统资源

  • 当用户并发量越高,需要消耗的资源越多,如何提供这些计算资源,如何构建一个系统,使这些资源能够有效的整合起来,为用户提供服务,这就是高并发情况下系统架构的挑战

应对高并发挑战的两个技术方向

  • 垂直伸缩:通过增强单一服务器的计算资源,提升计算能力,提升系统处理能力,应对用户并发的压力和请求

  • 可作为最简单的短期伸缩性方案,存在伸缩物理极限

  • 达到某个程度后,增加计算能力需要更多的花费

  • 水平伸缩:通过增加更多同类服务器,构成集群的分布式系统,共同对外提供服务,处理用户并发请求,提升整体计算能力,提升系统处理能力,应对用户并发的压力和请求



水平伸缩是目前互联网架构主要的技术手段

  • 这种水平伸缩的技术手段,正好应对了互联网系统本身渐进式发展的一个发展趋势或发展路径,当系统本身在不断的在渐进式发展,变得越来越大,用户不断增加的时候,总是可以通过增加服务器的方式提升系统的处理能力,来应对业务的发展和用户量的增加,这种增加通常也是线性的

  • 水平伸缩需要构建集群,进行分布式部署和管理,增加系统复杂度,对架构技术提出了挑战

二、系统架构的演化



分布式系统如何设计,服务器如何增加到分布式集群中,增加进来的服务器分别承担着什么样的角色,它们之间的关系是什么样的。它经历了怎样的一个变化过程,我们通过互联网的系统架构演化看下这个过程:

第0阶段:单一应用服务器

  • 应用程序,数据库部署在同一服务器,文件系统为服务器本地文件系统

第1阶段:应用和数据分离

  • 应用程序,数据库系统,文件系统分别部署在三台服务器上,构成简单的服务器集群,提升了三倍计算资源,一定程度上减少了资源争用(CPU,磁盘,内存),提高了处理能力,可以处理更多的用户请求。

第2阶段:使用缓存改善系统性能

  • 所谓的缓存是说,当我们需要访问的数据,存储在一个相对比较低速的存储上的时候,我们在低速的存储设备之间放一个高速的存储服务,这个高速的存储服务就是一个缓存服务。

  • 我们的数据库,文件数据都是存储在硬盘上的,硬盘的访问速度比较慢,我们可以把频繁访问的这些数据放到内存中,我们访问的时候,先到内存上去访问,看有没有我们需要的数据,如果有,我们直接就得到了数据,如果没有,我们再到数据库或文件系统去访问数据,得到数据后,把这个数据写入到缓存中,下一次就可以从缓存中得到我们想要的数据了。这个缓存是从内存存取的,它的访问速度通常远远快于文件或数据库的硬盘的。

  • 互联网架构中缓存有两种

  • 本地缓存

  • 远程分布式缓存,可以构建分布式缓存服务器集群,提供更大的数据存储能力,使内存中也可以存储很多数据

  • 使用缓存好处

  • 处理速度更快:加快了数据的访问速度

  • 资源消耗更小:因为缓存通常存储的是一个计算后的结果,从缓存中得到数据后,不需要再进行计算,直接得到计算结果,节约了CPU的时间,因为从缓存中得到数据,还降低了数据库或文件系统的访问压力,使数据库或文件系统可以处理更重要更迫切的一些其他服务和访问要求

  • 仍存在的问题

  • 使用了缓存以后,数据可以快速的通过缓存来获得,当高并发的用户来请求的时候,对应用服务器又造成了挑战,单一的一台应用服务器,并不能够满足高并发的用户连接,首先,每个用户连接都会消耗一定的资源,然后每个用户请求在处理过程中又会消耗一些资源,那么一个应用服务器是满足不了高并发的用户的访问要求的,我们需要进入架构演化的第三个阶段,构建一个应用服务器集群

第3阶段:使用应用服务器集群改善系统的并发处理能力

  • 我们需要构建一个应用服务器集群,通过负载均衡调度服务器,将用户请求分发给不同的应用服务器,每个应用服务器处理一部分用户请求,这样即使用户请求并发很高,用户量很多,他们的请求是分摊给应用服务器集群里的多台服务器上的,每一台服务器处理的并发请求并不高,整个应用系统,整个分布式集群,能够处理的并发用户请求就相对比较高了

第4阶段:数据库读写分离

  • 前一阶段通过负载均衡,构建应用服务器集群,每台应用服务器都只处理一部分的用户请求,从而使整个集群能够处理大量的高并发的用户请求,但是这些用户请求进来以后,需要进行很多的计算操作,其中一些计算操作和数据库相关的,但是数据库只有一台,虽然有一些数据的读操作可以通过缓存来访问返回,但是还是有一些数据,必须要通过数据库去读取,而所谓的写操作也必须要写入到数据库中,这个数据库就会成为整个系统的瓶颈,因为缓存是在内存中的,应用程序是在内存中进行计算的,只有数据库的数据是在硬盘上的,它的速度相对比较慢,如果每个用户操作都需要访问一次或者多次数据库,对数据库就会造成比较大的访问压力,虽然有很多的应用服务器,能够处理很多的并发用户请求,但是大家都等待数据库的处理结果,而数据库如果处理速度比较慢,应用程序里面用户请求的这些线程就不得不阻塞等待数据库的返回结果,虽然他们能够处理很多的并发请求,但是却都堵塞在内存中,不能够及时的响应,那么还是会有一些用户访问请求超时,糟糕的情况下,大量的用户超时,系统感觉就好像崩溃了一样。

  • 解决数据库访问的压力最简单的一个解决方案就是,我们使用主从分离的方式,把数据库部署为一个主服务器一个从服务器,实现读写分离。当我们有写数据的时候,要更新数据的时候,我们将数据写入到主数据库中,然后通过数据库之间的的主从复制,将数据复制到从服务器上面去;当我们要读数据的时候,我们从从服务器上面去读取数据,这样就可以减轻主数据库的访问压力;我们将数据库数据部署在两台服务器上面,近似的认为提升了一倍的处理能力,通过数据库的读写分离,提升数据库的处理能力,降低数据处理对整个系统造成的影响,以此来提升系统整个的并发处理能力

第5阶段:使用反向代理和CDN加速网站响应

  • 所谓的CDN是指内容分发网络,内容分发网络是部署在网络运营商机房里面的一个服务器,我们访问的互联网应用系统的服务器是部署在互联网的数据中心的,淘宝、百度、QQ它们的服务器都是部署在阿里、百度、腾讯的服务器机房里的,那么我们的网络请求是如何到达这些服务器机房的呢?我们需要通过网络运营商给我们提供网络链接服务,由网络运营商帮我们把请求分发到不同的服务器网站的机房里面去,那么我们想要的数据就可以直接缓存在网络运营商的机房里,这就是CDN的由来。

  • CDN的服务器是部署在网络运营商机房里的一台缓存服务器,当我们访问一个互联网应用的时候,我们的数据网络通信首先到达网络服务器运营商的机房里,网络服务器的机房就可以在本地的CDN服务器里面,去检查有没有我们想要的数据,如果有,那么直接就可以返回,而这个服务器通常是离我们访问者比较近的一个服务器,在这个CDN服务器里面缓存的用户数据,通常是一些静态的数据,一些静态的页面,一些CSS、JS脚本,一些图片这样的静态资源,当用户访问的时候,通过CDN服务器就可以直接返回,从而加快响应速度,用户的请求根本还没有到达网络服务商网站的机房,就已经得到了请求了,所以它的访问速度会更快,对整个网站系统的压力也更小,从而使网站节约更多的资源,处理更高的并发用户请求。

  • 对于很多大型的互联网应用而言,它们会构建一个CDN的集群,它们在各个网络运营商(电信铁通)的机房里,部署它们的CDN服务器,就近为用户提供服务,加快访问的速度,减轻自己机房里的系统的访问压力。

  • 如果CDN中没有缓存数据,访问的图片或内容不在CDN中,CDN就会将这个请求继续向下转发到它的数据中心,进入数据中心以后,第一层服务器就叫反向代理服务器,我们上网的时候,有时会用代理服务器,帮我们代理上网,而反向代理服务器是代理整个机房提供服务的,反向代理服务器主要承担的职责,依然是一个缓存的职责,反向代理服务器检查请求的资源在本机有没有,如果有,通过本机直接返回,如果没有,再将这个请求继续向下转发,通过负载均衡服务器分发到应用服务器里面去,进行计算处理。

  • 我们通过CDN和反向代理服务器已经可以处理绝大多数的用户请求,真正通过负载均衡到达服务器的请求已经变得很少了,就意味着有更多的用户,可以通过负载均衡和应用服务器进行处理,整个集群的处理能力变得更强大了,可以处理的并发用户可以更多了,系统整体的处理能力增强了

第6阶段:使用分布式文件系统和分布式数据库系统

  • 我们在前面通过数据库的主从复制,已经将数据库的读写进行了分离,写操作访问一个数据库,读操作访问另一个数据库,从而使数据库的处理能力得到提升,但是这种提升是很有限的,一方面,整个的数据的存储能力并没有提升,主数据库和从数据库存储的数据是完全一样的,另一方面,数据库写只能够写到主数据库上,所以写的操作只能够有一台服务器来完成,如果我们要存储的数据特别多,比如说我们要存储几十亿几百亿条记录,它可能在一个数据库上就无法完成存储,单一的服务器存不下一张表;还有大量的并发的写操作,要写数据库,一台服务器可能根本就不能够满足我的写操作的处理要求

  • 解决方法就是使用分布式的关系数据库,将数据库进行分片处理,你有十亿条记录,然后我把十亿条记录,分布在一百台服务器上,每个服务器上存储一千万记录,由一百台服务器构成一个分布式的数据库集群,共同对外提供服务,这时候用户的写操作会分摊到一百台服务器上进行处理,而数据的存储也是存储在一百台服务器上,那么它的存储能力提升了一百倍,它的写操作的并发处理能力提升了一百倍,数据库的处理能力,也就提升了这么多,整个系统的处理能力得到了相应的提升,可以处理的并发请求用户就更多了。

  • 同样的,文件系统也通过同样的方式,将文件分布在一个服务器的集群上,每个服务器上存储一部分的文件,整个集群存储更多的文件,将文件存储的访问压力和数据的存储分布在了多台服务器上,构建了一个分布式的服务器集群。

  • 通过分布式的数据库和分布式的文件系统,整体系统的磁盘或者文件的读写能力就得到了极大的提升,当我们需要有更多的文件或数据需要存储的时候,我们只需要增加更多的分布式数据库服务器和分布式文件服务器就可以了,系统的处理能力就得到了提升,整个系统能够处理的并发能力也得到了提升,就可以服务更多的并发用户请求

第7阶段:使用NoSQL和搜索引擎

  • 虽然分布式数据库已经可以存储更多的数据,可提供更高并发的数据库的写操作能力,但是还是有一些数据存储场景是分布式数据库不能够满足的,或者满足起来并不完美的,我们使用NoSQL数据库

  • 数据库的查找操作可以通过分布式数据库完成,但是分布式数据库对模糊查找支持的并不好,对于一些复杂的查询操作,它的处理操作也比较慢,我们可以通过搜索引擎来完成这样的数据查找

  • 通过NoSQL和搜索引擎进一步的提高数据的存储能力和数据的查询速度,进而提高整个系统的并发处理能力

第8阶段:业务拆分

  • 通常一个应用系统在早期的时候,它的功能是比较简单的,它的代码量也是比较少的,但是随着用户的增加,各种各样的用户提出了各种各样的需求,一方面这些更多的用户对并发处理提出了更高的挑战,另一方面也对功能提出了更多的要求,系统为了满足这些功能,为了满足用户的需求,就会变得也来越复杂,越来越庞大,代码量就会变得越来越多,里面的功能模块越来越多,业务越来越复杂,整个系统越来越庞大,架构演化的第八个阶段就是对这些业务进行拆分,对于电商系统,买家和卖家我们拆分成不同的应用服务器里面去,更进一步的,我们的搜索服务,我们的商品列表服务,我们的商品详情服务,我们的购物车服务,我们的订单服务,都作为不同的业务拆分成不同的服务器里去,部署到不同的服务器上,一则让这些业务进行拆分以后,开发和维护变得更加简单,同时这些服务部署在不同的集群上,它们的扩容,或者集群的伸缩,也变得更加的灵活,整个的处理能力也变得更加的强大,业务的发展也变得更加的灵活和快速。

  • 这些不同的业务之间可以通过简单的RPC调用,HTTP调用,也可以通过异步的消息队列进行通信,应用A产生的服务推送给消息队列服务器,应用B从消息队列服务器中获取消息,进一步的处理,业务之间进行了互相的依赖和调用,但是它们之间却没有直接的耦合,通过消息队列服务器进行通信,实现业务的拆分和依赖

第9阶段:微服务及中台化

  • 拆分后的一些业务,它们可能会依赖一些相同的服务,不管是搜索列表、详情、购物车还是订单,这些不同的应用,它们都会依赖用户服务,都会依赖商品服务,或者公共的一些服务,这些服务如果要是在每个业务服务器中都进行部署,甚至都分别进行开发,显然是比较昂贵,成本比较高的,也比较复杂的,那么最好的方法是,把这些公用的服务拆分出来,构建一个独立的微服务集群,这些服务部署在一个服务器集群上,对这些应用提供服务,这些应用需要用户服务的时候,就去调用用户的微服务服务器,当它需要商品服务的时候,就去调用商品的微服务服务器集群,这些用户、商品、支付、订单、消息各种各样的服务构建成了各种各样的微服务集群,然后供应用服务器调用,应用服务器只需要处理好自己的业务逻辑就可以了,关键的公用的服务由微服务服务器来提供,就是所谓的微服务架构。

  • 而这些微服务统一起来,它们可以供更复杂的产品调用,各种各样的产品都依赖这些微服务的时候,所谓的中台就建立起来了,新的产品开发的时候只需要依赖中台里面提供这些服务,基于这些服务定制的规范,开发他们的产品就可以了,他们只需要包装他们的产品的前端,而这些基础的服务由微服务和中台来提供,就是所谓的微服务和中台化

  • 微服务是我们目前互联网系统架构的主要架构模式,微服务架构里面一方面关注微服务之间的调用如何完成,更重要的是关注微服务本身如何设计,服务间的依赖关系如何设计,如何对服务进行建模

第10阶段:大数据与智能化

  • 在前面的互联网阶段,主要还是系统提供各种各样的功能和服务,用户对它进行访问,所有的这些功能和服务对用户来说是统一的,但是互联网走到了今天,更多的是对不同的用户提供不同的服务,根据用户个人的自身特点提供不同的服务,使系统呈现出一些智能化的特点来,典型的就是像今日头条这样的产品,不同的用户访问看到的内容是不一样的,每个用户都看到他们感兴趣的内容,这种所谓的千人千面,个性化推荐,来源就是大数据与智能化技术,通过大数据的分析和挖掘,然后发现不同用户的偏好,发现内容之间的关联,为不同的用户提供不同的推荐内容,从而实现系统的智能化,这些智能化它的前提就是大数据,需要构建一个大数据平台,通过大数据进行数据的分析和挖掘。

  • 大数据的数据从哪里来,这些数据如何进行处理,最后处理的结果如何推荐给用户供用户访问,就是大数据平台要关注的内容

三、案例:维基百科技术架构

全球访问量第六大互联网系统

  • GeoDNS:基于地理位置的域名服务器,多机房部署,部署三个数据中心,用户通过GeoDNS域名解析,就近访问数据中心

  • LVS:负载均衡服务器

  • Squid:反向代理缓存服务器集群,缓存词条页面,缓存图片

  • Apache PHP:应用服务器集群,实现业务逻辑,处理用户请求,查找数据,构建词条对象,构建页面内容,返回给用户

  • Memcached:分布式对象缓存集群,缓存词条数据对象

  • MySQL:核心关心数据库,存储词条数据,主从复制,读写分离

  • Lighttpd:图片服务器,动静分离,图片内容是静态的,PHP是动态的,二者分别部署,Squid根据域名访问不同的服务器获取内容

  • Lucene:搜索服务器集群,用户搜索操作

  • Invalidation notification:缓存的词条页面内容失效通知Squid进行删除



发布于: 2020 年 10 月 12 日 阅读数: 47
用户头像

piercebn

关注

还未添加个人签名 2019.07.24 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营 1 期第 4 周:系统架构 - 总结