集群与负载均衡

什么是集群

维基百科中是这样解释 集群 的:

计算机集群(英语:computer cluster)是一组松散或紧密连接在一起工作的计算机。由于这些计算机协同工作,在许多方面它们可以被视为单个系统。与网格计算机不同,计算机集群将每个节点设置为执行相同的任务,由软件控制和调度。

集群最明显的特点是一组计算机共同工作,且每台计算机执行相同的任务。通常我们会将这类计算机称之为服务器,而部署了应用程序的服务器我们称之为服务节点,下面的文章中我会使用服务器这个称呼来代替计算机,用服务节点来指代部署了应用程序的服务器。

如下图所示,我们有一组服务器编号 1 ~ 4,分别独立部署了程序 A,就形成了如下有 4 台服务器节点组成的程序 A 的集群。

在了解了什么是集群后,我们思考一个问题,为什么我们要通过集群的形式来部署应用程序呢?

举个例子,不知道你有没有去火车站的售票大厅来购买火车票。

在 12306 出现之前,火车票的主要售卖渠道是火车站的售票大厅,如果是工作日,有出行需求的旅客较少,通常火车站只需要开放少量的购票窗口,就足以应对旅客的购票需求了。

但是等到了春节这种客流量巨大的节日,火车站需要开放所有的售票窗口来应对巨大的人流量,虽然没有提高单个售票窗口的售票能力,但是通过增加更多的售票窗口,也能够大大提高售票大厅的整体售票能力,从而减少旅客购票时所需的排队时间。

如果我们把单个售票窗口看做��服务器,售票员就是部署的应用程序,那么售票员与售票窗口的组合就形成了售票工作的服务节点,多个售票工作的服务节点组合起来就形成了火车站售票工作的集群,那么对于这样一个集群来说,能够带来什么好处呢?

集群能够提高服务的整体性能

最显而易见的是,通过不断地开放窗口增加售票员,火车站整体的售票能力得到了非常显著的提升。单个售票员的售票能力是有上限的,无论进行怎样的培训和流程优化,都不可能突破人类的生理极限,那么通过开放新的售票窗口增加售票员实现并行售票,就能够轻松提升火车站的整体售票能力。

其实,服务器也是这样的,每台服务器的处理能力都是有理论上限的,即便通过各种方式优化软硬件,也只是能够接近理论上限,而无法突破理论上限。如果想要再去提高整体服务的处理能力,最简单的办法就是“新开窗口增加售票员”,即加入新的服务器部署相同的应用程序作为服务节点,以此来实现服务的并行处理,提高服务的整体处理能力。

那么使用集群的方式部署应用程序带来的第一个优点是:提高性能,通过增加服务节点来提高并行处理能力,能够轻松提高服务的整体处理能力。

集群能够实现服务的高可用

我们再来考虑另外一个问题,人的生老病死是不可避免的,如果火车站只配备一个售票员,一旦售票员生病请假甚至是辞职,那么火车站就要停止售票吗?很明显这样是不行的,因此火车站需要配备多名售票员,一旦某个售票员短时间内(甚至是永久)无法进行工作,那么其他售票员就可以分担掉这些工作,保证火车站的售票工作正常运转。

同样的,服务器也可能出现各种各样的故障,应用程序也能出现意想不到的异常,一旦某个服务器或者是应用程序不可用,那么集群内部署的其它服务器就可以及时的分担掉客户端发送的请求,保证服务的整体是正常运转的。

那么使用集群的方式部署应用程序带来的第二个优点是:通过服务节点的互相容错,能够提高集群系统的可用性,单个服务节点或多个服务节点的宕机并不会影响系统的整体运行。

集群部署能够灵活拓展

对于火车站来说,平日旅客较少的时候不必开放全部的售票窗口,只需要少量的售票窗口就可以满足乘客的购票需求,而运到春运这种客流量激增的情况时,可以通过快速的加开窗口来提高整体的售票能力,减少旅客的等待时间。

同样的,平日流量较少的时候,只需要部署少量的服务器就可以满足日常的需求,一旦遇到流量激增的情况,可以通过增加服务器的手段来应对。

那么使用集群的方式部署应用程序带来的第三个优点是灵活拓展,当遇到流量高峰,通过部署新的服务节点来缓解系统的压力,当流量高峰过去,可以通过释放这些服务节点去处理其它工作

集群部署能够降低成本

这点是很容易被忽略的,集群部署的场景中通常使用基于 X86 架构的标准硬件来当做服务器,入门级的产品可能也就是 5000 元左右的价格,对比入门门槛动辄十几万甚至上百万的大型服务器来说,价格可谓是非常的亲民。

而且在大部分场景下,服务的负载并不会很高,大型服务器可能会长时间处于空闲的状态,这就造成了性能浪费,如果根据实际负载情况替换成多台标准硬件,就能够极大的降低成本,即便是遇到流量高峰,也可以通过横向拓展增加服务器的方式来应对。

况且,基于现在各家提供的云服务和灵活的付费方式,能够非常简单快速的进行横向拓展和实现按量购入。

什么是负载均衡

通过集群部署的方式,虽然提高了服务的整体性能和可用性,但随之而来的我们需要解决两个问题:

  1. 客户端的请求该如何均匀的分发到集群中的服务器上?
  2. 如果某个服务节点宕机,该如何避免将请求分发到这台服务器上?

对于火车站来说,旅客可以通过观察来确定售票窗口是否提供服务,以及排队人数和售票员的工作能力,来选择去哪个售票窗口排队;而有些火车站则在售票大厅配备了引导员,指挥旅客去正在提供服务并且旅客人数较少的窗口排队购票,这样就解决了旅客选择窗口排队的问题。但是,对于计算机系统来说,该如何解决这两个问题呢?

为此,计算机科学家们引入了 负载均衡

负载平衡(英语:load balancing)是一种电子计算机技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到优化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。 使用带有负载平衡的多个服务器组件,取代单一的组件,可以通过冗余提高可靠性。负载平衡服务通常是由专用软件和硬件来完成。 主要作用是将大量作业合理地分摊到多个操作单元上进行执行,用于解决互联网架构中的高并发和高可用的问题。

维基百科的解释中涉及到了硬件负载的内容,但是对软件开发领域来说,负载均衡主要用于将客户端请求分配到集群中不同服务器上进行处理,以实现客户端请求的均匀分配,达到提高吞吐率,降低响应时间,减少单台服务器使用率的目的

分发请求

通过维基百科中定义的描述,我们可以知道负载均衡的一项核心能力就是:分发请求

分发请求的工作是通过负载均衡策略算法完成的,常见的算法如轮询,加权轮询,随机以及最小连接数等,每种算法所使用的场景不同,可以根据具体的业务场景来选择合适的算法,以达到均匀且合理的分配请求

通过负载均衡算法,可以解决分发请求的问题,那么该如何避免将请求分发到已经宕机的服务器上呢?

健康检查

负载均衡的另一项核心能力是:健康检查,所谓的健康检查,就是后端服务器进行健康状态的检查。

我们以某云的负载均衡 SLB 举例,SLB 自身会维护一个可用服务列表,当请求到达 SLB 时,通过负载均衡算法从可用服务列表中选择一个可用服务。同时,SLB 还会定时向可用服务列表中的服务发送探测包,相应服务接收到探测包后,根据服务的运行状况返回 HTTP 状态码,SLB 会根据响应时间,以及 HTTP 的状态码来判断该服务是否可用,如果不可用,SLB 会将该服务从可用服务列表中剔除。虽然各家的负载均衡对健康检查的具体实现方式会略有不同,但原理都是大致相同的。

除了以上两项核心能力外,负载均衡还会支持会话保持,对于需要保持会话状态的服务,负载均衡应该要确保同一客户端的请求始终被分发到同一台服务器上,以此来保持会话的连续性。

实现方式

负载均衡的实现方式主要有两类:通过硬件实现和通过软件实现

通过硬件实现负载均衡

通过硬件实现负载均衡指的是通过专用设备(负载均衡器)来实现负载均衡,例如:F5 的 BIG IP,Radware 的 Alteon 等。这种方式与火车站增加引导员非常相似,负责均衡器负责将客户端发送的请求分配到可用的且负载较低的服务器上,以实现合理分发请求。

通常负载均衡器的性能会非常高,因为是为大流量而研发的专用设备,它的重心就是提高吞吐量,高效的处理和转发请求。但缺点也很明显,成本昂贵,无论是前期购买的费用,还是后期专人维护的费用,都不是小公司能够负担得起的。

通过软件实现负载均衡

通过软件实现负载均衡指的是通过部署专用软件来实现,与负载均衡根器不同的是,负载均衡软件可以部署在常规设备(或云)上,如:Nignx,Apache HTTP Server 等。

这种方式的特点最显著的两个特点是:成本低和灵活性高。以 Nginx 为例,我们可以将 Nginx 部署在基于 X86 架构的服务器上,也可以部署到云上,相较于负载均衡器,不仅成本低,而且非常灵活。

缺点也是显而易见的,性能瓶颈非常明显,相较于专为负载均衡而生的负载均衡器,Nginx 等软件只是在软件层面做了优化,而无法触及硬件层面的优化,“好马还需配好鞍”才能发挥出最强大的性能。

除了 Nginx,Apache HTTP Server 等负载均衡软件外,还有一类客户端负载均衡软件,如 Ribbon,Spring Cloud LoadBalancer 等,它们集成在客户端程序中,通过注册中心获取服务列表并分发请求,作为后端程序员,我们会更关心这类负载均衡框架。

注意:

  • 无论是 Nginx 还是 Apache HTTP Server,负载均衡只是它们众多功能中的一项;
  • 因为 Ribbon 的停更,Spring Cloud 已经移除了对 Ribbon 的依赖,默认使用 Spring Cloud LoadBalancer 来替代。

常见负载均衡算法

负载均衡算法可谓是负载均衡的核心,它决定着是否能够均匀且合理的分配请求,下面我简单介绍一些常见的负载均衡算法。

随机法

顾名思义,随机法就是在可用服务列表中随机选择服务并分发请求

优点:

  • 原理和实现方式非常简单(不包括随机数生成算法)
  • 能够保证长时间运行后的公平性

缺点:

  • 短时间内可能多次随机到同一台服务器上,导致服务器负载较大
  • 无法根据服务器的性能做出针对性的调整
  • 无法根据服务器响应状态做出调整
加权随机法

加权随机法是随机法的升级版,通过为可用服务列表中的每个服务添加权重,以此来提升某些服务被选中的概率。假设有编号 1~4 的 4 台服务器,我们为每台服务器设置相应的权重:

那么通过加权随机法可以构建出如下服务器的随机范围:

优点:

  • 原理和实现方式都很简单
  • 能够保证长时间运行后的结果趋近于预设的权重
  • 可以根据服务器性能做出相应的调整

缺点:

  • 依旧无法避免短时间多次随机到同一台服务器上的问题
  • 无法根据服务器响应状态做出调整
  • 服务器性能量化难度高,导致权重设置困难
轮询法

轮询法的实现也很简单,按照可用服务列表中的顺序,逐个分发请求即可。假设有 4 台服务器编号 1~4,负载均衡会按照顺序依次分发请求:

优点:

  • 原理和实现方式非常简单
  • 能保证近乎绝对的公平性

缺点:

  • 无法根据服务器的性能做出针对性的调整
  • 无法根据服务器响应状态做出调整
加权轮询法

加权轮询法是轮询法的升级版,为可用服务列表中的每个服务添加权重,以此来增加某些服务被轮询到的次数。加权轮询法和加权随机法非常相似,我这里采用加权随机法中使用的权重分配,负载均衡可以根据权重分配构建出如下的轮询顺序:

通常情况下会将权重较高的服务打乱,避免一轮轮询中连续请求到同一台服务器上。

优点:

  • 原理和实现方式都很简单
  • 可以根据服务器性能做出相应的调整

缺点:

  • 无法根据服务器响应状态做出调整
  • 服务器性能量化难度高,导致权重设置困难
最小连接数法

通过收集与记录后端服务器的连接数,选择连接数最小的服务分发请求。最小连接数法是基于服务器的实际负载情况来分发请求的,可以比较合理的将请求分发到每一台服务器上。 优点:

  • 原理非常简单
  • 能够根据实际情况动态调整

缺点主要集中在实现难度上:

  • 准确和及时的收集后端服务的连接数,如果收集数据不准确或者不够及时,可能导致请求分发不够合理
  • 需要对集群中每个服务的链接数进行对比,当集群中服务数量非常大时,对比算法的优劣会成为影响负载均衡效率的关键因素

以上 5 种算法应该是最常见的负载均衡算法了,常见的软件/框架中都对它们有所支持,比如:

DubboSpring Cloud LoadBalancerRibbonNginx
随机法不支持支持支持不支持
加权随机法支持不支持支持不支持
轮询法不支持支持支持支持
加权轮询法支持不支持支持支持
最小连接数法支持,但是做了改进不支持支持支持

上述列举的软件/框架中,除了 Spring Cloud LoadBalancer 只有两种默认的负载均衡算法实现外,其余的还支持更多种的负载均衡算法,而且它们都支持自定义负载均衡算法。

负载均衡算法远不止列举出来的这些,还有诸如源地址哈希法,最小响应时间法,以及大名鼎鼎的一致性哈希算法等,介于篇幅的原因我就不再这里一一介绍了(部分���法会通过单独的文章和大分享)。

好了,今天的内容就到这里了,我们下次再见~~

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值