一、常见概念
1.1 基本概念
- 应用(Application)/ 系统(System)
- 为了完成一套服务的一个程序或一组相互配合的程序群
- 模块(Module)/ 组件(Component)
- 一个应用中中很多功能,每一个独立的功能就能被称为模块/组件
- 分布式(Distributed)
- 引入多个主机/服务器,协同配合完成一系列工作(物理上的)
- 集群(Cluster)
- 引入多个主机/服务器,协同配合完成一系列工作(逻辑上的)
- 主(Master)/ 从(Slave)
- 分布式中一种常用的框架,多个服务器节点,其中一个为主,其他的为从,从服务器中的数据需要从主服务器中同步
- 中间件(Middleware)
- 中间件通常指的是和业务无关的服务(更加通用的服务),例如:数据库、缓存、消息队列等
1.2 系统评判标准
- 可用性(Availability)
- 考察单位时间段内,系统可以正常提供服务的概率/期望。例如:年化系统可用性=系统正常提供服务时长/一年总时长
- 响应时长(Response Time RT)
- 指用户完成输入到系统给出用户反应的时长
- 吞吐(Throughput)
- 考察单位时间段内,系统可以成功处理的请求的数量
- 并发(Concurrent)
- 系统同一时刻支持的请求最高量
二、单机架构
单机架构就是只有一台服务器,这个服务器需要负责所有的工作。
假设这里有一个电商网站,下面的应用服务就是我们写的应用服务器,例如在C++中我们使用cpp-httplib所写的HTTP服务器,一个电商网站还需要大量的数据需要存储,所以还需要一个数据库服务用来存储数据。
大部分数据库都是客户端服务器程序,例如MySQL就是一个客户端服务器程序的一个服务器,MySQL的本体是服务器,也就是存储和组织数据的部分,而应用服务就是MySQL的客户端。
大家不要看不上单机架构,现在的计算机硬件发展迅速,一台主机的性能也是很高的,可以支持非常高的并发和非常多的数据,绝大部分公司使用的都是单机架构。
三、引入分布式
随着业务进一步增长,用户量和数据量也会随之增长,当一台主机无法处理时,就需要引入更多的硬件资源,引入更多的主机。
一台主机的资源是有限的,例如:CPU、内存、磁盘、网络等,服务器没收到一个请求就会消耗一些资源,当同一时间有大量请求的时候,就可能导致服务器的资源不够用,导致服务器处理速度慢火处理出错的情况。
如果遇到服务器资源不够用的情况,有两种方式解决:
- 开源,增加更多的硬件资源
- 节流,软件上进行优化,通过性能测试,找到哪个环节导致服务器不够用,然后进行优化,这很考验程序员的能力
如果选择了开源的处理方式,就可以升级硬件性能或增加硬件数量,但是一台主机能增加的硬件资源是取决于主板扩展能力,也就是说一台主机能增加的硬件资源数量是有限的。
当扩展能力到达极限后,还不足以满足需要,就只能增加主机的数量了。但是并不是说买来主机就能够解决问题了,还需要对软件做出对应的调整和适配才能解决。
当引入了多台主机以后,系统就可以被称为分布式系统了。看到这里,大家不要非常向往分布式系统,因为分布式系统是在迫不得已的情况下,才会被选择的,因为使用分布式系统以后,系统的复杂程度就会成倍增加,系统出现BUG的概率也就越大,所以不要轻易使用分布式系统。
四、应用服务和数据库服务分离
当系统中引入了两台主机后,就可以将应用服务和数据库服务分开,使用一台作为应用服务器,专门用来处理应用服务,然后再使用一台作为存储服务器,专门用来处理数据存储问题。
这样讲应用服务和数据库服务分离就可以使的应用服务器和存储服务器相对独立,可以根据它们对应的服务,选取对应的硬件,例如:应用服务器需要处理很多业务逻辑,就更加需要CPU和内存资源,可以为应用服务器配备更好或更多的CPU和内存资源;存储服务器需要更大的存储空间和更快的访问速度,就可以配置更大的硬盘。这样做可以让系统更有性价比。
五、引入更多的应用服务器(负载均衡)
5.1 引入更多的应用服务器
如果只有一台应用服务器,并且应用服务器在运行的过程中,CPU或内存资源被消耗完后,此时服务器就可能挂掉。
这时候就可以引入多台应用服务器,用户的请求首先会到达负载均衡器,然后通过负载均衡器对请求进行分配,使得请求会被相对公平的分配给每一个应用服务器,这样就可以减少应用服务器的压力了。
如果说所有的请求都会先到达负载均衡器,那么会不会负载均衡器承受不住呢?
负载均衡器对于请求量的承担能力是远超与应用服务器的。大家可以理解为负载均衡器是领导,它会将它收到的任务分配给员工,应用服务器是员工,执行领导分配的任务。我们都知道执行任务的消耗是一定会远远超过分配任务的。所以负载均衡器一般是承受的住的。
但是还是可能会出现请求量太大导致负载均衡器承受不住的情况,此时就可以引入更多的负载均衡器。
这里举个例子,假设一个大学中,新生报到处就是负载均衡器,导员就是应用服务器。假设一个学生来到学校后,需要先到新生报到处进行报道,然后通过里面的工作人员将学生分配给导员,一个大学中导员是用来管理学生的,若一个学校的学生很多就需要很多的导员来管理学生。随着时间的发展,报考这个学校的人越来越多,导致开学时,目前的新生报到处已经无法分配这么多学生后,就可以再新增一个新生报到处(负载均衡器),所有新生报到处共享同一份导员名单和分配规则,然后通过这些新生报到处一起分配学生给导员。
当人越来越多以后,管理成本就会越来越高,问题出现的概率就会增加。同理当机器变得越来越多,管理成本也会随之提高,出现的问题的概率也会增加。
引入负载均衡还有一个好处,就是当其中一个应用服务器崩溃以后,其他服应用服务器可以承担起它的服务,也就提高了系统的可用性。
5.2 负载均衡的分类
负载均衡有多种分类方式,我这里按照算法策略分类,分别列举几个负载均衡的方式:
- 静态负载均衡
- 轮询(Round Robin):依次分配请求,均匀但无视服务器负载
- 加权轮询(Weighted Round Robin):根据服务器权重分配流量
- IP 哈希(IP Hash):相同 IP 的请求固定分配到同一服务器(保持会话)
- 动态负载均衡
- 最少连接(Least Connections):优先分配给当前连接数最少的服务器
- 最短响应时间(Least Response Time):优先选择响应最快的服务器
- 基于资源利用率:根据 CPU、内存等实时负载动态调整
六、读写分离
如上面讨论的一样,增加应用服务器的数量确实能够减轻每台应用服务器的压力,但是对于存储服务器的请求数量却是更多了。那么应该如何解决这个问题呢?
还是开源+节流,节流这里就不讲了,需要很高的门槛。开源,也就是引入更多的机器,将这些机器都作为存储服务器,并将这些机器分为主服务器和从服务器。
这里就要引入读写分离的概念了,读写分离是一种数据库架构设计模式,其核心思想是:将数据库的读操作(查询)和写操作(增删改)分离到不同的服务器上,以适应 读多写少 的业务场景(在数据库的实际应用场景中,读的频率要远高于写的频率的)。
在读写分离的框架中,通常是采用了单主多从的设计。主服务器独享写权限,并通过复制机制将数据同步给从服务器。从服务器提供读服务,同时还可以通过负载均衡的方式,让应用服务器可以较为平均的对从服务器进行访问。
七、引入缓存
我们知道数据库有一个天然的缺点就是响应慢,想要解决这个问题,我们就可以在系统中引入缓存。
我们知道二八原则,20%的人拥有80%的财富,同样在数据库这里也适用,数据库中的数据,20%的数据能够支持80%的数据访问,又缓存的访问速度比磁盘的访问速度快很多,我们只需要将大量被访问的数据存放到缓存中,就可以加快响应速度和减少从服务器的压力。当应用服务器需要读数据时,会先会在缓存中查找,缓存中没有就会去从服务器中查找,由于缓存中存储的数据是会被大量访问的,所以通常应用服务器想要查找的数据都能在缓存中查到。
八、数据库分库分表
引入分布式系统的目的不只是为了解决更高的请求量,还需要解决更大数据量的问题。
虽然说现在一台数据库服务器能够存储的数据量已经非常庞大了,但是还是可能会出现一台数据库服务器不能将数据全部存储下来的情况。
还是之前的老办法开源,引入更多的主机来存储数据。这时候我们根据数据库进一步进行拆分。本来一个数据库服务器就需要存储很多个数据库(指的是逻辑上的数据集合,create database),现在就可以引入多个数据库服务器,每个数据库服务器存储一个或多个数据库。同理,如果遇到一个数据库服务器存不下一个表,也可以将表进行对应的拆分,具体的拆分方法,需要有具体的业务逻辑。
存储服务器vs数据库服务器
- 存储服务器
- 提供数据存储和基础读写能力(如文件、块、对象存储)
- 适用于存储图片、视频、日志等非结构化数据
- 数据库服务器
- 提供结构化数据管理,支持SQL查询、事务、索引等高级功能
- 适用于处理订单、用户信息等需要复杂查询和事务的业务数据
存储服务器中是可以安装数据库的。如果存储服务器中安装数据库,此时存储服务器就需要同时承担数据库服务器的角色。
九、微服务
之前的应用服务器,都是一个服务器中实现很多业务,但是这样会导致服务器的代码越来越复杂。
为了后期更简单的维护代码,我们就可以将复杂的服务器,拆分成多个功能单一,更小的服务器。但是这样做会增加应用服务器的数量和种类。
当应用服务器越来越复杂,就需要更多的人进行维护,人多了就需要配套的管理把这些人管理好,划分组织架构,分成多个组,进行分工合作。之前应用服务器实现全部的业务,并不方便后期的维护,我们按照功能拆分为多个微服务,这样也就有利于上述公司人员的分组。所以引入微服务本质上是解决了人的问题。
我们知道引入一个功能,势必需要一些代价,而引入微服务的代价:
- 系统性能下降。本来复杂的服务器中,不同业务之间的互相调用,只需要进程间通信即可,而拆分后,更多依靠的就是通过网络实现调用,势必导致系统性能下降。要保证性能不下降太多,就需要更好的硬件资源,更多的机器了
- 系统复杂度提高,可用性受到影响。服务器更多了,出现的问题的概率就会更大,就需要通过一系列手段来保证系统的可用性。例如:配备更加丰富的报警装置,配备一个配套的运维人员
结尾
如果有什么建议和疑问,或是有什么错误,大家可以在评论区中提出。
希望大家以后也能和我一起进步!!🌹🌹
如果这篇文章对你有用的话,希望大家给一个三连支持一下!!🌹🌹