网站系统架构演进
![网站系统架构演进](https://static001.geekbang.org/infoq/cd/cde255017e6e3d5dc84af81b56c3bcef.jpeg)
今天,我们来整理《大型网站技术架构》这本书中,关于网站系统架构演进的这一部分。
其实,现在互联网公司里的系统架构演进,跟这个几乎是一致的。对比我现在公司的产品架构演进历程来看,也是大同小异的。
技术书的整理我觉得分两种,一种是看到一个技术点,然后结合同主题的其他资料来做深入的研究、编码实践,然后整理成例子和文章。
另一种就属于抄书了,尤其这本书,很干而且还接近是最通俗易懂的语言了。
本来还想着划重点,整理重要内容出来强化记忆,最后发现里面的每一字每一句都近乎最简单的语言了,李老师真的很厉害。
大型的网站架构肯定都是演进出来的,像微信肯定也不是一开始就奔着亿级流量来设计的。如果一开始就画太大的饼,没有权衡好资源,那么结果可想而知:先帝创业未半而中道崩殂。
以下是一个网站,从 0 到 1;以及从 1 到 100 的架构演进历程:
1、初始阶段的网站架构
网站搭建之初,没有知名度,流量小的可怜。那么我们只需要一台服务器就绰绰有余了,应用程序、数据库、文件系统等等所有资源都部署在一台服务器上。
而开发的技术采用最简单的开源框架即可,最常见的是:Linux + Java + Apache + mySQL。
![](https://static001.geekbang.org/infoq/0e/0e03a607b2c88b982484e962f45b0b36.png)
2、服务器拆分
随着网站发展,一台服务器已经不能满足流量请求了。
而且各个不同类型服务,对服务器资源的要求差异性是不同的,例如:
应用服务器需要处理大量请求的业务逻辑,因此需要更快更强大的 CPU;
数据库服务器需要快速磁盘检索和数据缓存,因此需要更快的硬盘(SSD)和更大的内存;
文件服务器需要存储大量用户上传的文件,因此需要更大的硬盘。
![](https://static001.geekbang.org/infoq/9f/9f1e18cba71d32d87065e2674080493f.png)
我们依据不同服务的特性来定制不同类型服务器的硬件资源,达到资源的最大利用。这时候网站的并发处理能力和数据存储能力都得到了很大的改善。
3、使用缓存改善网站性能
随着用户量的增多,网站面临新的挑战:数据库压力太大导致访问延迟,影响了整个网站的性能,用户体验受到影响。
网站的访问特点也是遵循二八原则的:80% 的业务访问集中在 20% 的数据上。因此我们使用缓存,就能极大地降低数据库的负载压力,从而提升整个系统的性能。
缓存这一大杀器,在很大场景中都能有奇效,在各个层级中都能看到缓存对于性能提升的贡献,之后我们还会看到。
![](https://static001.geekbang.org/infoq/c5/c5705fc53c565f40bb9616013b20e62d.png)
缓存又分两种:应用的本地缓存(例如 Jvm 缓存);专门的分布式缓存服务器(redis、codis)。
本地缓存速度更快一些,不过受应用内存限制,而且还会占用应用的内存。适合缓存少量的超热点数据。
分布式缓存服务器可以搭建成集群的模式,理论上可以做到不受内存容量限制。因为是可扩展的。
4、应用集群部署
数据库访问压力得到释放之后,单一的应用服务器处理能力成为了整个系统的瓶颈。这时候,使用集群化部署是解决网站高并发、海量数据的常用手段。不过,这就要求我们的系统是可伸缩的。
通过增加服务器来线性提高系统并发能力,应该是成本最低且最简单的手段了。通过负载均衡和应用无状态实现线性伸缩,将会在系统伸缩性设计这一篇文章中做介绍。
![](https://static001.geekbang.org/infoq/45/4554677be5b4cd872f828c67c218c19d.png)
5、数据库读写分离
网站在使用缓存后,数据库的压力能大大地减少。可是仍有一部分数据要落到数据库层操作(缓存访问不命中、缓存过期等),以及全部的写操作都要访问数据库。当用户量持续增大后,数据库的负载压力无可避免地会升高,最后成为网站的瓶颈。
我们能利用数据库的主从热备功能,简单地实现数据库的读写分离,主数据库只负责写请求,分离读写的请求来分摊主库的负载压力。
而我们的应用服务器,一般都会通过统一的客户端来进行数据库操作,实现数据库主从分离对应用的透明,同时也减少代码的侵入。
![](https://static001.geekbang.org/infoq/10/101b040ef2560c9add574760438c0bf9.png)
6、使用反向代理和 CDN 加速网站响应
这个属于前端优化了,请求到达应用服务器之前的优化都属于前端优化。
这里我们也能看到缓存的身形,本质也是使用缓存快速地响应用户的请求。区别在于:
CDN 缓存是部署在网络运营商的机房,能够根据用户浏览器所在地使用最接近用户的缓存;
反向代理是部署在网站自己的中心机房,请求到达中心机房后,如果有缓存就直接返回给用户,不再做进一步的分发。
![](https://static001.geekbang.org/infoq/7f/7fb682beac30a5cfdbd0398bf56c70a6.png)
缓存的目的都是尽早返回数据给用户。一方面是加快用户响应速度,一方面是减轻下一层的服务压力。
7、使用分布式文件系统和分布式数据库系统
任何强大的单一服务器都满足不了大型网站持续增长的业务需求,所以分布式会是服务演进路上的一个重要手段。
不过分布式数据库是数据库拆分的最后手段了,更常用的手段是简单地通过分库分表来实现性能的提升。系统的伸缩性扩展性这篇文章里有说到分布式数据库,数据的查询和组合实现成本较高,而且有时候需要业务上的妥协。
![](https://static001.geekbang.org/infoq/a2/a278f892f66ad31789575a2536380e0f.png)
8、使用 NoSQL 和搜索引擎
NoSQL 和搜索引擎对可伸缩的分布式特性有更好的支持。应用服务器通过一个统一的数据访问模块来控制访问,减轻应用服务的代码侵入和数据源管理的麻烦。
![](https://static001.geekbang.org/infoq/10/100c2c305d7e8b9941f8046d30ce47bc.png)
9、业务拆分
网站发展愈加庞大,就会分而治之,拆分成不同的业务和产品线,交由不同的团队来负责。
具体到技术上,一个网站可以拆分成许多不同的应用,每个应用独立部署维护,这就是时下流行的微服务。
应用和应用怎么建立关联:
可以通过一个超链接来建立关系(例如首页上的各个导航链接);
也可以通过消息队列来进行数据分发;
最常用的还是通过访问同一个数据存储系统来构成一个关联的完整系统。
![](https://static001.geekbang.org/infoq/aa/aaf0caaea0f4e01286aa3b960782bcc3.png)
10、分布式服务
网站架构横向的拆分可以按业务和产品线来拆分成微服务。那么纵向的拆分就可以拆分成分布式服务。
试想,如果不进行分布式服务的拆分,我们每个应用服务器都直接连接数据库资源,随着应用拆分的越来越多,最终会导致数据库连接资源不足,成为系统的瓶颈。
我们可以把业务之间可复用的部分拆分提取出来,独立部署。由这些服务来进行数据库的连接和访问操作,应用服务只需要管理用户界面,然后通过调用这个分布式服务来完成具体的业务操作。
![](https://static001.geekbang.org/infoq/91/9147819ffbd81ec13f960f33cd8b36d3.png)
最后,网站架构演进到这里,基本上大多数高并发、海量数据问题都能得到处理了。遇到问题时,分析当前瓶颈是哪一节,然后通过上述的技术组合来解决实际中的业务问题。
评论