天天看点

互联网架构演进模型1、单机网站架构2、应用与数据分离3、使用缓存改善网站性能4、应用服务器集群5、数据库读写分离6、使用反向代理和CDN加速网站响应7、数据库的分库分表(垂直/水平拆分)及分布式文件系统8、使用NoSQL和搜索引擎9、按业务模块拆分10、服务化及中间件 总结

小网站发展成大型网站的过程,就像游戏中的升级打怪一样,不同的阶段需要不同的技能。网上有很多架构演进的文章,不过他们更多的讲的是每次演进的结果,并没有很详细的讲为什么需要这样的演变。

本文将通过一个包含用户模块、商品模块和交易模块的时尚电商网站来阐述一个小网站发展成大型网站的过程中所遇到的问题、解决方案和所需要掌握的知识体系。这个发展过程是一种较为典型的架构演变历程,不管您的公司目前处于哪个阶段,总能找到适合您公司下一个阶段的框架及所需要了解的知识。

分布式架构的演进过程如下:

1、单机网站架构

2、应用与数据分离

3、使用缓存改善网站性能

页面缓存、页面片段缓存、数据缓存

4、应用服务器集群

5、数据库读写分离

6、使用反向代理和CDN加速网站响应

7、数据库的分库分表(垂直/水平拆分)及分布式文件系统

8、使用NoSQL和搜索引擎

9、按业务模块拆分

10、服务化及中间件

1、单机网站架构

假如我们要做一个时尚电商网站,网站最开始的时候只有一些朋友圈的好友访问,这时只需要一台服务器就够了。应用程序、数据库、文件等所有的资源都放到这台服务器上,可以采用LAMP(linux+apache+mysql+php)架构或linux+tomcat+maven+springboot+mybatis+mysql架构,这些都是开源软件,可以在网上很方便的找到并安装。

互联网架构演进模型1、单机网站架构2、应用与数据分离3、使用缓存改善网站性能4、应用服务器集群5、数据库读写分离6、使用反向代理和CDN加速网站响应7、数据库的分库分表(垂直/水平拆分)及分布式文件系统8、使用NoSQL和搜索引擎9、按业务模块拆分10、服务化及中间件 总结

单机网站架构

这一阶段涉及到的知识体系:LAMP(linux+apache+mysql+php)或linux+tomcat+maven+springboot+mybatis+mysql

2、应用与数据分离

随着用户量的增加,服务器的负载慢慢提高,导致性能越来越差,数据量越来越多也导致存储空间不足。假如我们代码层面已难以优化,在不提高单台机器性能的情况下,可以通过增加机器的方式将应用和数据分离,分离后系统分为三台服务器:应用服务器、文件服务器和数据库服务器。

互联网架构演进模型1、单机网站架构2、应用与数据分离3、使用缓存改善网站性能4、应用服务器集群5、数据库读写分离6、使用反向代理和CDN加速网站响应7、数据库的分库分表(垂直/水平拆分)及分布式文件系统8、使用NoSQL和搜索引擎9、按业务模块拆分10、服务化及中间件 总结

应用与数据分离

这三台服务器对硬件资源的要求各不相同:应用服务器需要处理大量的业务逻辑,因此需要更快更强大的CPU;数据库服务器需要快速磁盘检索和数据缓存,因此需要更快的磁盘和更大的内存;文件服务器需要存储大量用户上传的文件,因此需要更大的磁盘。

优点:应用服务器跟数据服务器分离后,不同特性服务器承担不同的服务角色,系统并发能力和存储能力都得到了很大加强,并且不会因为数据库和应用形成互相的影响。

这一阶段涉及到的知识体系:这一步架构演变对技术上的知识体系基本没有要求。

3、使用缓存改善网站性能

好景不长,随着访问的人越来越多,响应速度又开始变慢了,查找原因,发现是访问数据库的操作太多,导致数据连接竞争激烈,所以响应变慢,因此考虑采用缓存机制来减少数据库连接资源的竞争和对数据库读的压力。

从缓存的对象来分类,后端缓存可以分为:页面缓存、页面片段缓存和数据缓存。页面缓存:我们可以把系统中相对静态的页面(例如一两天才会有更新的页面)进行缓存,可以采用squid 等类似的机制,也可以采用将页面静态化的方案。页面片段缓存:我们可以把动态页面里相对静态的部分也缓存起来,可以采用类似ESI之类的页面片段缓存策略。数据缓存:大家都知道80%的业务访问集中在20%的数据上,我们可以考虑把这部分热数据放到缓存中,以降低数据库的压力。

从缓存的存储来分类,后端缓存可以分为:本地缓存和远程缓存。本地缓存:基于内存,访问速度更快,但是受限于硬件资源大小。远程缓存:可以使用Redis或Memcache等内存数据库,采用集群部署,理论上不限容量。

互联网架构演进模型1、单机网站架构2、应用与数据分离3、使用缓存改善网站性能4、应用服务器集群5、数据库读写分离6、使用反向代理和CDN加速网站响应7、数据库的分库分表(垂直/水平拆分)及分布式文件系统8、使用NoSQL和搜索引擎9、按业务模块拆分10、服务化及中间件 总结

使用缓存改善网站性能

优点:对于一些页面和热数据采用缓存后,可以极大的降低数据库服务器的压力,提高网站性能。

这一阶段涉及到的知识体系:页面缓存技术,例如squid等类似的机制;页面静态化;页面片段缓存技术,例如ESI等;一致性Hash算法;Redis或Memcache等内存数据库的相关知识;

4、应用服务器集群

随着系统访问量的再度增加,应用服务器的压力越来越大,遇到访问高峰时,甚至会成为系统的短板,同时单台应用服务器如果down机的话,系统就无法访问了。为了解决性能和可用性的问题,我们跟公司申请,增加了两台应用服务器。应用服务器实现集群化是一种成熟的可伸缩架构。

这时我们会遇到以下问题:

1)用户的请求如何转发到某台具体的应用服务器?

2)用户如果每次访问到的应用服务器不一样,如何维护session的一致性?

3)如何保持数据缓存信息的同步,例如之前缓存的用户数据等?

4)如何让上传文件等类似的功能继续正常?

第一个问题即是负载均衡的问题,一般有5种解决方案:http重定向、DNS域名解析负载均衡、反向代理服务器、IP层负载均衡和数据链路层负载均衡,每种解决方案都各有优劣。解决负载均衡问题的软件一般有:Apache自带的负载均衡方案、LVS这类的软件负载均衡方案、keepalived+ipvsadm、nginx等,目前很多公司采用nginx来实现负载均衡。

第二个问题是session问题,一般有四种解决方案:Session Sticky、Session Replication、Session数据集中存储和Cookie Base,下面简单介绍下这四种解决方案:

Session Sticky:session sticky就是把同一个用户在某一个会话中的请求,都分配到固定的某一台服务器中,这样我们就不需要解决跨服务器的session问题了,常见的算法有ip_hash法。优点:实现简单。缺点:应用服务器重启则session消失。

Session Replication:session replication就是在集群中复制session,使得每个服务器都保存有全部用户的session数据。优点:减轻负载均衡服务器的压力,不需要要实现ip_hasp算法来转发请求。缺点:复制时宽带开销大,访问量大的话session占用内存大且浪费。

Session数据集中存储:session数据集中存储就是利用数据库来存储session数据,实现了session和应用服务器的解耦。 优点:相比session replication的方案,集群间对于宽带和内存的压力减少了很多。缺点:需要维护存储session的数据库。

Cookie Base:cookie base就是把session存在cookie中,有浏览器来告诉应用服务器我的session是什么,同样实现了session和应用服务器的解耦。优点:实现简单,基本免维护。缺点:cookie长度限制,安全性低,宽带消耗。

第三个问题可以采用缓存同步或分布式缓存方法解决。

第四个问题通常使用的是共享文件系统或存储等。

互联网架构演进模型1、单机网站架构2、应用与数据分离3、使用缓存改善网站性能4、应用服务器集群5、数据库读写分离6、使用反向代理和CDN加速网站响应7、数据库的分库分表(垂直/水平拆分)及分布式文件系统8、使用NoSQL和搜索引擎9、按业务模块拆分10、服务化及中间件 总结

应用服务器集群

优点:应用服务器集群化之后,可以支持更大的用户访问量,同时单台服务器down机的话,用户请求可以实时切换到其他服务器上,系统无影响。

这一阶段涉及到的知识体系:

负载均衡技术:包括但不限于硬件负载均衡、软件负载均衡、负载算法、linux转发协议、所选用的技术的实现细节等

主备技术:包括但不限于ARP欺骗、linux heart-beat等

状态信息或缓存同步技术:包括但不限于Cookie技术、UDP协议、状态信息广播、所选用的缓存同步技术的实现细节等

共享文件技术:包括但不限于NFS等

存储技术:包括但不限于存储设备等

5、数据库读写分离

有一天你会发现,由于添加的webserver太多了,导致数据库连接的资源还是不够用,这个时候你开始分析数据库的压力状况,可能会发现数据库的读写比很高,这个时候通常会想到数据库读写分离的方案。

数据库的读写分离是建立在主从热备的基础上的,基本目前大多数主流数据库都支持主从热备,通过配置两台或者多台数据库的主从关系(1主1从,1主多从,多主多从),实现数据的读(从库)写(主库)分离,主库主动将数据同步到从库。分离之后,写到主库,从从库读,但是这样会带来几个问题:

1)主从的数据库之间的数据同步:可以使用mysql自带的master-slave方式实现主从复制

2)对应的数据源的选择:可以采用第三方数据库中间件,例如:mycat,mycat是国内比较好的mysql开源数据库分库分表中间件。

互联网架构演进模型1、单机网站架构2、应用与数据分离3、使用缓存改善网站性能4、应用服务器集群5、数据库读写分离6、使用反向代理和CDN加速网站响应7、数据库的分库分表(垂直/水平拆分)及分布式文件系统8、使用NoSQL和搜索引擎9、按业务模块拆分10、服务化及中间件 总结

数据库读写分离

优点:一般情况下,读请求量会远高于写请求,读写分离后,当读请求比较大的时候,可以横向扩展从库服务器,从而支持更大的访问量。

这一阶段涉及到的知识体系:数据读写分离要求对数据库的复制、standby等策略有深入的掌握和理解,同时要求具备自行实现的技术。

6、使用反向代理和CDN加速网站响应

为了进一步加快网站的访问速度,可以考虑使用CDN和反向代理。CDN部署在网络提供商的机房,当用户访问时,可以从距离用户最近的网络提供商机房获取数据。反向代理部署在网站自己的中心机房,当用户请求到达机房时,优先访问的服务器是反向代理服务器,如果反向代理中缓存了用户请求的资源,那么就直接返回给用户,加快了响应的速度,也减轻了后端负载的压力。CDN与反向代理的基本原理都是缓存。

互联网架构演进模型1、单机网站架构2、应用与数据分离3、使用缓存改善网站性能4、应用服务器集群5、数据库读写分离6、使用反向代理和CDN加速网站响应7、数据库的分库分表(垂直/水平拆分)及分布式文件系统8、使用NoSQL和搜索引擎9、按业务模块拆分10、服务化及中间件 总结

使用反向代理和CDN加速网站响应

这一阶段涉及到的知识体系:需要了解CDN和反向代理相关的知识

7、数据库的分库分表(垂直/水平拆分)及分布式文件系统

我们的网站演进到现在,用户、商品、交易的数据都还在同一个数据库中。尽管采取了增加缓存,读写分离的方式,但随着数据库的压力继续增加,数据库的瓶颈越来越突出,此时,我们可以采用分库分表两种方法进行解决。

分库:又叫垂直拆分,就是把数据库中不同的业务数据拆分到不同的数据库中,结合现在的例子,就是把用户、商品、交易的数据分开。优点:解决了原来把所有业务放在一个数据库中的压力问题,可以根据业务的特点进行更多的优化。缺点: 需要维护多个数据库。

分库所遇到的问题:1)需要考虑原来跨业务的事务;2)跨数据库的join

解决方案:在应用层尽量避免跨数据库的事物,如果非要跨数据库,尽量在代码中控制。我们可以通过第三方应用来解决,如上面提到的mycat,mycat提供了丰富的跨库join方案,详情可参考mycat官方文档。

分表:又叫水平拆分,就是把同一个表中的数据拆分到两个甚至多个数据库中。产生数据水平拆分的原因是某个业务表的数据量或者更新量到达了单个数据库的瓶颈,这时就可以把这个表拆分到两个或更多个数据库中。优点: 如果我们能克服单个表过大的问题,那么我们将能够很好的应对数据量快速增长的情况。

分表所遇到的问题:

1)访问用户信息的应用系统需要解决SQL路由的问题,因为现在用户信息分在了两个数据库中,需要在进行数据操作时了解需要操作的数据在哪里。

2)主键的处理也变得不同,例如原来自增字段,现在不能简单地继续使用了。

3)如果需要分页,处理起来比较麻烦。

解决方案:我们还是可以通过第三方中间件来解决,如mycat。mycat可以通过SQL解析模块对我们的SQL进行解析,再根据我们的配置,把请求转发到具体的某个数据库。 我们可以通过UUID保证唯一或自定义ID方案来解决主键问题。 mycat也提供了丰富的分页查询方案,比如先从每个数据库做分页查询,再合并数据做一次分页查询等等。

分表是系统数据库拆分的最后方法,只有在单表数据规模非常庞大的时候才使用,更常用的数据库拆分手段是业务分库,将不同的业务数据库部署在不同的物理服务器上。截止到目前,我们的数据库已经改成了分布式数据库,这时我们还可以采用分布式文件系统,用来应对数据量的大幅度增长。

互联网架构演进模型1、单机网站架构2、应用与数据分离3、使用缓存改善网站性能4、应用服务器集群5、数据库读写分离6、使用反向代理和CDN加速网站响应7、数据库的分库分表(垂直/水平拆分)及分布式文件系统8、使用NoSQL和搜索引擎9、按业务模块拆分10、服务化及中间件 总结

数据库的分库分表(垂直/水平拆分)及分布式文件系统

这一阶段涉及到的知识体系:了解第三方中间件比如mycat,在分库分表中的应用。

8、使用NoSQL和搜索引擎

随着网站业务越来越复杂,对数据存储和检索的需求也越来越复杂,网站需要采用一些非关系型数据库(NoSQL)和非数据库查询(搜索引擎)技术,这时我们可以引入NoSQL数据库及搜索引擎。应用服务器通过统一数据访问模块访问各种数据,减轻应用程序管理诸多数据源的麻烦。

数据库做读库的话,常常对模糊查找力不从心,即使做了读写分离,这个问题还未能解决。以我们所举的交易网站为例,发布的商品存储在数据库中,用户最常使用的功能就是查找商品,尤其是根据商品的标题来查找对应的商品。对于这种需求,一般我们都是通过like功能来实现的,但是这种方式的代价非常大。此时我们可以使用搜索引擎的倒排索引来完成。

搜索引擎的优点:它能够大大提高查询速度。

引入搜索引擎后也会带来以下的开销:

1)带来大量的维护工作,我们需要自己实现索引的构建过程,设计全量/增量的构建方式来应对非实时与实时的查询需求。

2)需要维护搜索引擎集群

搜索引擎并不能替代数据库,他解决了某些场景下的“读”的问题,是否引入搜索引擎,需要综合考虑整个系统的需求。引入NoSQL和搜索引擎后的系统结构如下:

互联网架构演进模型1、单机网站架构2、应用与数据分离3、使用缓存改善网站性能4、应用服务器集群5、数据库读写分离6、使用反向代理和CDN加速网站响应7、数据库的分库分表(垂直/水平拆分)及分布式文件系统8、使用NoSQL和搜索引擎9、按业务模块拆分10、服务化及中间件 总结

使用NoSQL和搜索引擎

这一阶段涉及到的知识体系:

搜索引擎:例如Elasticsearch、Solr、Sphinx等

NoSQL:例如MongoDB、Hbase、Cassandra等

9、按业务模块拆分

当业务模块越来越多,同时用户达到一定的级别后,需要通过分而治之的手段将系统分成多个模块,不同模块划分不同业务团队负责。具体到技术上,也会根据不同模块进行拆分,每个模块独立开发维护和部署。

互联网架构演进模型1、单机网站架构2、应用与数据分离3、使用缓存改善网站性能4、应用服务器集群5、数据库读写分离6、使用反向代理和CDN加速网站响应7、数据库的分库分表(垂直/水平拆分)及分布式文件系统8、使用NoSQL和搜索引擎9、按业务模块拆分10、服务化及中间件 总结

按业务模块拆分

这一阶段涉及到的知识体系:业务模块拆分,工作量比较大,需要对各业务非常熟悉,且非常认真负责。

10、服务化及中间件

随着业务的拆分越来越小,系统的复杂度呈指数级上升,部署维护越来越困难。这时会面临以下问题:

1)业务拆分后,可能会有一些相同的代码,如用户相关的代码,商品和交易都需要用户信息,所以在这两个系统中都保留差不多的操作用户信息的代码,这些代码如何可复用?

2)由于所有的应用都需要跟数据库进行连接,导致数据库的连接资源不足,拒绝服务

为了解决这些问题,我们需要将公用的功能进行独立提取,独立部署,向外提供可复用的统一分布式服务,这种方式又叫SOA。服务化之后,相同的代码不会散落在不同的应用中了,这些实现放在了各个服务中心,使代码得到更好的维护,同时我们把对数据库的交互放在了各个服务中心,让前端的web应用更注重与浏览器的交互工作,而新增业务也只需要调用这些分布式服务。但是同时,我们又遇到以下问题:

1)如何进行远程的服务调用

2)随着网站的继续发展,我们的系统中可能出现不同语言开发的子模块和部署在不同平台的子系统。此时我们需要一个平台来传递可靠的,与平台和语言无关的数据,并且能够把负载均衡透明化,能在调用过程中收集调用数据并分析之,推测出网站的访问增长率等等一系列需求,对于网站应该如何成长做出预测。

这时我们可以通过引入消息中间件的方式来解决,例如阿里的dubbo,可以搭配Google开源的分布式程序协调服务zookeeper实现服务器的注册与发现。这一步的架构图如下:

互联网架构演进模型1、单机网站架构2、应用与数据分离3、使用缓存改善网站性能4、应用服务器集群5、数据库读写分离6、使用反向代理和CDN加速网站响应7、数据库的分库分表(垂直/水平拆分)及分布式文件系统8、使用NoSQL和搜索引擎9、按业务模块拆分10、服务化及中间件 总结

服务化及中间件

这一阶段涉及到的知识体系:需要识别可复用的业务,设计服务接口,规范服务依赖关系;要求对通信、远程调用、消息机制等有深入的理解和掌握,要求的都是从理论、硬件级、操作系统级以及所采用的语言的实现都有清楚的理解;运维这块涉及的知识体系也非常的多,多数情况下需要掌握分布式并行计算、报表、监控技术以及规则策略等等。

通常,演进到这一阶段需要耗费相当长的时间,也会碰到很多挑战:

1)拆成分布式后需要提供一个高性能、稳定的通信框架,并且需要支持多种不同的通信和远程调用方式;

2)将一个庞大的应用拆分需要耗费很长的时间,需要进行业务的整理和系统依赖关系的控制等;

3)如何运维(依赖管理、运行状况管理、错误追踪、调优、监控和报警等)好这个庞大的分布式应用。

经过这一步,差不多系统的架构进入相对稳定的阶段,同时也能开始采用大量的机器来支撑着巨大的访问量和数据量,结合这套架构以及这么多次演变过程吸取的经验来采用其他各种各样的方法来支撑着越来越高的访问量。

 总结

设计网站架构时一定要从小开始,架构随业务演变而演变,切记不要在业务还是0的时候去追求1的架构设计,那样的架构只会舍本逐末,得不偿失。整个网站架构的经典演变过程都和上面比较的类似,当然,每步采取的方案,演变的步骤有可能会不同,另外,由于网站的业务不同,会有不同的专业技术的需求,这篇文章更多的是从架构的角度来讲解演变的过程,当然,其中还有很多的技术也未在此提及,像数据挖掘、实时数据统计等,并且在真实的演变过程中还会借助像提升硬件配置、网络环境、改造操作系统等来支撑更大的流量,因此在真实的发展过程中还会有很多的不同。一个大型网站要做到的远远不仅仅上面这些,还有像安全、运维、运营、服务、存储等,要做好一个大型的网站真的很不容易。

下一篇: UVA 11995

继续阅读