随着互联网应用和云计算的普及,架构设计和软件技术的关注重点已从实现复杂业务逻辑逐渐转变为满足大量用户的高并发访问需求。一个简单的计算过程,在面对大量用户访问时会带来截然不同的技术挑战,这也直接影响到软件开发方法、技术团队组织以及软件过程管理方式,推动它们发生全面转型。
以新浪微博为例,最初该项目由两位工程师负责,一个前端和一个后端,他们在一周内就完成了新浪微博的开发。然而,随着时间的推移,新浪微博的技术团队已经扩大到上千人。这支团队面临的技术挑战主要来源于两个方面:一是日益复杂的功能需求,二是用户数量的增加所带来的高并发访问压力。
这种挑战和压力几乎普遍存在于所有大型互联网系统中,比如淘宝、百度和微信等。尽管这些平台的功能各不相同,但它们都必须应对相似的高并发用户访问请求。需要注意的是,同样的功能,如果是供少数人使用,与供几亿人使用,其技术架构差异是巨大的。
当同时访问系统的用户数量不断增加时,系统所需消耗的计算资源也随之上升。这意味着需要更多的 CPU 和内存来处理用户的请求,更多的网络带宽来传输数据,以及更多的磁盘空间来存储用户的信息。一旦资源消耗超过了服务器的承载极限,服务器就可能崩溃,导致整个系统无法正常运行。
垂直伸缩与水平伸缩
为应对高并发用户访问所带来的系统资源消耗,一种常见的解决方案是垂直伸缩。垂直伸缩指的是提升单台服务器的处理能力,例如,通过更快频率的 CPU、更多核心的 CPU、更大容量的内存、更快的网卡,以及更多的磁盘来增强单台服务器的性能。这种方法可以有效提升系统的处理能力。
在大型互联网应用出现之前,传统行业(如银行和电信)主要依赖垂直伸缩来提升系统能力。随着业务增长和用户数量的增加,当服务器的计算能力无法满足需求时,企业通常会选择更强大的计算机,逐步更换更快的 CPU、更大的内存和磁盘,或者将服务器从小型机升级到中型机,再到大型机。虽然服务器的处理能力不断增强,但其成本也随之上升,运维管理的复杂性也增加了。
垂直伸缩所带来的成本与服务器处理能力之间并不一定呈线性关系。这意味着,即使投入相同的费用,也不一定能够获得相应的计算能力。此外,随着计算能力的提升,所需的资金支出往往会显著增加。同时,受限于计算机硬件科技的水平,单台服务器的计算能力无法无限制地增加,而互联网,尤其是物联网的计算需求几乎是无止境的。因此,在互联网及物联网领域,垂直伸缩并不是首选方案,反而更倾向于采用水平伸缩。
水平伸缩的核心在于不再提升单台服务器的处理能力,而是通过增加更多的服务器来构建一个分布式集群。该集群能够统一对外提供服务,从而提高整体系统的处理能力。要实现这一点,需要在架构设计上进行充分考虑,将多台服务器有效地整合,使其成为系统的一个整体,从而实现资源的统一管理与处理能力的提升。这一策略已成为互联网应用和云计算中普遍采用的分布式架构方案。
互联网分布式架构演化
分布式架构是互联网企业在业务快速发展过程中,逐渐发展起来的一种技术架构,包括了一系列的分布式技术方案:分布式缓存、负载均衡、反向代理与 CDN、分布式消息队列、分布式数据库、NoSQL 数据库、分布式文件、搜索引擎、微服务等等,还有将这些分布式技术整合起来的分布式架构方案。
这些分布式技术和架构方案是互联网应用随着用户的不断增长,为了满足高并发用户访问不断增长的计算和存储需求,逐渐演化出来的。可以说,几乎所有这些技术都是由应用需求直接驱动产生的。
下面我们通过一个典型的互联网应用的发展历史,来看互联网系统是如何一步一步逐渐演化出各种分布式技术,并构成一个复杂庞大的分布式系统的。
在最早的时候,系统因为用户量比较少,可能只有几个用户,比如刚才提到的微博。一个应用访问自己服务器上的数据库,访问自己服务器的文件系统,构成了一个单机系统,这个系统就可以满足少量用户使用了。
图片
如果这个系统经过验证在业务上是可行且有价值的,那么用户量将会迅速增长。例如,新浪微博通过引入一些明星大V开通微博,迅速吸引了大量粉丝关注。在这种情况下,服务器将无法承受不断增加的访问压力,因此需要进行首次升级,具体措施是将数据库与应用进行分离。
图片
在系统最初的单机架构中,数据库和应用程序是部署在同一台服务器上的。当进行首次分离时,应用程序、数据库和文件系统被分别部署到不同的服务器上,从一台服务器扩展为三台服务器,从而使处理能力提升了三倍。这一分离过程几乎不需要额外的技术成本,只需将数据库和文件系统进行远程部署并进行远程访问即可。
然而,随着用户数量的进一步增加,微博吸引了越来越多的粉丝,三台服务器也开始无法满足这种增长带来的压力。此时,为了改善系统性能,就需要引入缓存机制来进一步提升处理能力。
图片
所谓缓存,是指将应用程序需要读取的数据存储在缓存中,以便通过缓存来读取数据,而非直接从数据库中读取。缓存主要分为两种类型:分布式缓存和本地缓存。分布式缓存将多台服务器构成一个集群,共同存储更大规模的缓存数据,从而为应用程序提供更强大的缓存服务。
通过使用缓存,应用程序可以避免频繁访问数据库。因为数据库中的数据存储在磁盘上,访问数据库的速度相对较慢,而缓存中的数据则存储在内存中,访问速度更快。此外,数据库中的数据通常以原始形式存在,而缓存中的数据则往往以结果形式存在,例如已经构建好的对象,这样可以省去对象计算的时间,降低 CPU 的压力。
最重要的是,应用程序通过访问缓存可以显著降低对数据库的访问压力,而数据库通常是整个系统的瓶颈所在。因此,减少数据库的访问压力能够有效改善整个系统的处理能力。
随着用户的进一步增加,比如微博有更多的明星加入进来,并带来了更多的粉丝。那么应用服务器可能又会成为瓶颈,因为连接大量的并发用户的访问,这时候就需要对应用服务器进行升级。通过负载均衡服务器,将应用服务器部署为一个集群,添加更多的应用服务器去处理用户的访问。
图片
在微博平台上,用户的主要操作是浏览微博,也就是读取微博内容。在这种情况下,如果仅仅是明星发布微博,粉丝进行浏览,对数据库的访问压力相对较小,因为微博数据可以通过缓存进行提供。然而,实际上,粉丝们也会发微博,进行写入操作,这就会使得数据库再次成为整个系统的瓶颈。
单一的数据库难以承受如此巨大的访问压力。因此,此时的解决方案是数据库的读写分离。具体而言,这一方案通过数据复制的方式将一个数据库分为两个部分:主数据库和从数据库。主数据库主要负责数据的写操作,所有的写入操作都会被复制到从数据库,以确保从数据库的数据与主数据库保持一致。而从数据库则主要负责处理数据的读取操作。这种方式有效减轻了主数据库的负担,提高了整个系统的性能和可扩展性。
图片
通过这种方式,将一台数据库服务器水平扩展为两台数据库服务器,可以显著提升数据处理能力。对于大多数互联网应用而言,这种分布式架构已经能够有效满足用户的并发访问压力。然而,对于更大规模的互联网应用,如新浪微博,还需要解决海量数据的存储与查询问题,以及由此产生的网络带宽压力和访问延迟等挑战。
随着业务的不断复杂化,系统的低耦合与模块化开发、部署也成为重要的技术难题。海量数据的存储主要通过分布式数据库、分布式文件系统和NoSQL 数据库来解决。仅仅在传统数据库上进行查询已无法满足这些数据的性能要求,因此需要部署独立的搜索引擎来提供高效的查询服务。同时,为了减轻数据中心的网络带宽压力并提升用户访问速度,可以利用CDN和反向代理提供前置缓存,从而快速返回静态文件资源给用户。
为了使各个子系统更加灵活且易于扩展,采用分布式消息队列来解耦相关子系统,通过消息的发布与订阅实现子系统间的协作。此外,应用微服务架构将逻辑上独立的模块在物理上也进行独立部署和维护,系统通过组合多个微服务来完成业务逻辑,从而实现更高级别的模块复用,促进系统的快速开发与维护。
图片
微服务、消息队列、NoSQL 等分布式技术在早期出现时,通常具有较高的技术难度和使用门槛,因此仅在一些大规模的互联网系统中得到应用。然而,近年来随着技术的不断成熟,尤其是云计算的普及,这些技术的使用门槛逐渐降低。如今,许多中小规模的系统也开始广泛采用这些分布式技术架构来设计和构建自己的互联网应用。