网站架构瓶颈解决方案(发展历程)

本篇文章参考《大型网站技术架构》,夹杂了一些个人理解,本人渣渣,如有不合理或不全面之处,还请各位指出,不胜感激。

首先,个人认为,网站的架构发展还是根据自家的瓶颈来改进演变,并无“一种架构演变方式打遍天下”一说,首先要找到自家网站的瓶颈,然后根据瓶颈来设计对策方案为好。

下面所述为演变方案之一:

1.初始阶段(单机架构)

有的网站(如后台管理系统),性质就决定了并发量,还有的2C的网站在初始阶段,并没有多大的访问量,因此一台服务器就绰绰有余(可用性会另说),这时的架构比较简单,我们称之为单机架构,如图

很多大型网站,都经历过这个阶段

2.服务分离

随着用户量的增多,网站逐渐出现性能瓶颈,这时我们可将应用服务和数据服务分离。

我们可将应用程序、文件服务和数据服务分别部署在不同的服务器上。

不同的服务可选择不同性能的服务器,比如应用程序要处理大量计算,我们可选择更快的CPU,数据库服务器可选择更大的磁盘和内存,文件服务可选择更大的磁盘。

3.数据库瓶颈

读请求和写请求都落在数据库服务器上,渐渐地,数据库服务器会不堪重负,为了解决这个问题,我们可以采用三个方案(或都采用,依据实际情况来定)

缓存

网站访问也存在二八定律:80%的业务访问集中在20%的热点数据上。如:淘宝买家浏览的商品集中在销量多、评价好的商品上;微博的热搜等。

既然大部分访问集中在小部分数据上,我们可把这一小部分数据(热点数据)缓存在内存中,即可减少数据库访问,改善网站性能。

缓存有两种方式:

  • 缓存在应用服务器的本地缓存中(访问快,但会占用应用服务器的缓存,因此不能缓存太多)
  • 缓存在专门的分布式缓存服务器上(要经过网络远程访问,但可缓存的东西较多)

读写分离

目前大部分主流数据库都提供主从热备功能,通过配置两台数据库的主从关系,可以将一台数据库服务器的数据更新同步到另一台服务器上。我们可以利用这一功能,实现数据库的读写分离,从而改善数据库负载压力。

应用服务器在写数据的时候,访问主数据库,主数据库通过主从复制机制将数据更新同步到从数据库,这样应用服务器读数据的时候,就可以通过从数据库获得数据。

为了便于应用程序访问读写分离后的数据库,通常在应用服务器端使用专门的数据访问模块,使数据库读写分离对应用透明。

分库分表

分库分表是数据库拆分的最后手段。

分库:将单个数据库按需求拆分(如:订单库、商品库等)

分表:在单表数据规模非常庞大的时候(千万级别),我们可进行分表,如按时间分等,比如饿了么只能看到近一年的订单,猜想它是进行了按订单时间定时分表的操作。

4.应用服务器瓶颈

之前有人说过,一个请求大概占2M内存。

随着请求数量的增加,应用服务器可能会出现性能瓶颈,这时我们有两种方式应对:

垂直扩展(不推荐)

一台服务器出现性能瓶颈,就更换内存更大、CPU更快或是磁盘更大的服务器,这种扩展方式,我们称之为垂直扩展。

但是,我们用户数量可能是不设限的,我们不能丹丹依靠于单台硬件,不会有无限大的内存、硬盘,无限快的CPU来满足我们的需求,因此,这种扩展方式较为僵化,个人不推荐使用。

水平扩展

一台服务器出现瓶颈?那就多来几个服务器!通过负载均衡服务器,可将来自用户浏览器的访问请求分发到应用服务器集群中的任意一台服务器上。

再有瓶颈的情况,可通过再加入服务器的方式解决。

5.加速网站响应--反向代理和CDN

本质上,反向代理和CDN都是缓存。

CDN部署在网络提供商的机房,用户在请求网站服务时,可以从距离自己最近的网络提供商机房获取数据。

反向代理部署在网站的中心机房,当用户请求到达中心机房后,首先访问的服务器是反向代理服务器,如果反向代理服务器中缓存着用户请求的资源,求将其直接返回给用户。

6.搜索引擎

我们主要讲一讲垂直化搜索引擎,这里所说的垂直化搜索引擎,与大家所熟知的百度和Google存在一些差别。

垂直化搜索引擎主要针对企业内部的自有数据的检索,而不是像Google和百度等搜索引擎平台,采用爬虫对全网数据进行爬取,建立索引并提供给用户进行检索。

在我们的分布式架构中,垂直化搜索引擎是很重要的一个角色,它既能满足用户对于全文检索、模糊匹配的需求,解决数据库like查询效率低下的问题;又能够解决分布式环境下,由于采用分库分表或者使用NoSQL数据库,导致无法进行多表关联或者进行复杂查询的问题。

搜索引擎的几个重要概念:

倒排索引:又称反向索引,几乎所有的搜索引擎都会用到倒排索引。它将文档中的词作为关键字建立词与文档的映射关系,通过对倒排索引的检索,可以根据词快速获取包含这个词的文档列表。

分词:又称切词,即将句子或者段落进行切割,从中提取出包含固定语义的词。对于英语来说较为容易,因为英语的基本单位就是单词。但是对于中文来说,就比较困难了,常用的中文分词器包括一元分词(以字为单位切分)、二元分词(以两个字为单位切分)、词库分词(用词库中定义的词来进行切分)等。

索引的构建分为这样几个过程:通过指定的数据格式,将文档传递给分词器进行分词,然后通过索引写入工具将索引写入指定的目录。

7.异步

我们写代码,很重要的一点是降低耦合性,事物间的直接关系越少,就越少彼此影响,越可以独立发展。

在大型网站中,系统解耦合很重要的一个手段是异步调用,我们可以使用消息队列(如kafka、ActiveMQ等)实现异步调用。

好处如下:

提高系统可用性:消费者服务器发生故障,数据会在消息队列中堆积,对生产者无影响,系统整体表现无异常,待消费者故障恢复,继续消费消息队列中的数据。

加快网站响应速度:生产者在将数据写入消息队列即可返回,响应延迟减少。

消除并发访问高峰:“削峰填谷”面熟的就是这个场景,可以降低高峰时期的负载。

8.业务拆分

随着网站越来越复杂,部署维护变得越来越困难,据说某知名网约车公司项目启动要达十分钟之久。

于是我们可将业务进行拆分,如电商系统,我们可以将业务拆分为订单、商品等,一个部门专门负责一个部分,这样上线、维护都会简单一些,服务之间通过远程调用(现有许多成熟的RPC框架:WebService、dubbo等)完成业务操作。

猜你喜欢

转载自blog.csdn.net/qq_37043780/article/details/82946321