计算高性能[集群高性能]

  • 单服务器无论如何优化,无论采用多好的硬件,总会有一个性能天花板,当单服务器的性能无法满足业务需求时,就需要设计高性能集群来提升系统整体的处理性能
  • 高性能集群的本质很简单,通过增加更多的服务器来提升系统整体的计算能力。计算本身存在一个特点:同样的输入数据和逻辑,无论在哪台服务器上执行,都应该得到相同的输出 。因此高性能集群设计的复杂度主要体现在任务分配这部分,需要设计合理的任务分配策略,将 计算任务分配到多台服务器上执行
  • 高性能集群的复杂性主要体现在需要增加一个任务分配器,以及为任务选择一个合适的任务分配算法。对于任务分配器,现在更流行的通用叫法是“负载均衡器”。但这个名称有一定的误导性,会让人潜意识里认为任务分配的目的是要保持各个计算单元的负载达到均衡状态,而实际上任务分配并不只是考虑计算单元的负载均衡。不同的任务分配算法目标是不一样的,有的基于负载考虑、有的基于性能(吞吐量、响应时间〉考虑、有的基于业务考虑。负载均衡不只是为了计算单元的负载达到均衡状态。

负载均衡分类

常见的负载均衡系统包括 3 种: DNS 负载均衡、硬件负载均衡和软件负载均衡。

DNS负载均衡

DNS是最简单也是最常见的负载均衡方式,一般用来实现地理级别的均衡。例如,北方的用户访问北京的机房,南方的用户访问深圳的机房,DNS 负载均衡的本质是DNS解析同一个域名可以返回不同的IP地址,例如,同样是 www.baidu.com,北方用户解析后获取的地址是 61.135 .165.224,南方用户解析后获取的地址是 14 .2 15.177.38

DNS 负载均衡
计算高性能[集群高性能]_第1张图片
DNS负载均衡实现简单、成本低,但也存在粒度太租、负载均衡算法少等缺点

  • 简单 、成本低 : 负载均衡工作交给DNS服务器处理,无须自己开发或维护负载均衡设备
  • 就近访问,提升访问速度:DNS解析时可以根据请求来源IP,解析成距离用户最近的服务器地址,可以加快访问速度,改善性能
  • 更新不及时 : DNS 缓存的时间比较长,修改 DNS 配置后,由于缓存的原因,还是有很多用户会继续访问修改前的 I P ,这样的访问会失败,达不到负载均衡的目 的, 并且也影响用 户正常使用业务
  • 扩展性差 : DNS 负载均衡 的控制权在域名商那里 ,无法根据业务特点针对其做更多 的定制化功能和扩展特性
  • 分配策略比较简单 : DNS 负 载均衡支持的算法少:不能区分服务器的差异(不能根 据系统与服务的状态来判断负载);也无法感知后端服务器的状态

针对 DNS 负载均衡的 一 些缺点,对于时延和故障敏感的业务,有一些公司自 己实现了 HTTP-DNS 的功能,即使用 HTTP 协议实现一个私有的 DNS 系统。这样的方案和通用的 DNS优缺点正好相反。

硬件负载均衡

硬件负载均衡是通过单独的硬件设备来实现负载均衡功能,这类设备和路由器交换机类似,可以理解为一个用于负载均衡的基础网络设备。目前业界典型的硬件负载均衡设备有两款 : FS 和 A10 。这类设备性能强劲,功能强大,但价格都不便宜 , 一般只有“土豪” 公司才会考虑使 用此类设备。普通业务量级的公司一是负担不起,二是业务量没那么大,用这些设备也是浪费。

硬件负载均衡的优缺点如下

  • 功能强大 : 全面支持各层级的负载均衡,支持全面的负载均衡算法,支持全局负载均衡
  • 性能强大 : 对比一下,软件负载均衡支持到 10万级井发己经很厉害了,硬件负载均 衡可以支持 100 万以上的并发
  • 稳定性高 : 商用硬件负载均衡,经过了良好的严格测试,经过大规模使用, 在稳定性方面高
  • 支持安全防护 : 硬件均衡设备除具备负载均衡功能外,还具备防火墙、防 DDOS 攻 击等安全功能
  • 价格昂贵 : 几十万上百万
  • 扩展能力差:硬件设备,可以根据业务进行配置 , 但无法进行扩展和定制

软件负载均衡

  • 软件负载均衡通过负载均衡软件来实现负载均衡功能,常见的有Nginx和LVS, 其中Nginx 是软件的 7 层负载均衡,LVS是 Linux内核的4层负载均衡。4层和7层的区别就在于协议和 灵活性。 Nginx支持HTTP、E-mail 协议, 而LVS是4层负载均衡,和协议无关 ,几乎所有应 用都可以做,例如,聊天、数据库等
  • 软件和硬件的最主要区别就在于性能,硬件负载均衡性能远远高于软件负载均衡性能。 Ngxin的性能是万级,一般的Linux服务器上装一个Nginx大概能到5万/每秒:LVS的性能是十万级,据说可达到80万/每秒 ;而自性能是百万级,从200 万/每秒到800 万/每秒都有,当然,软件负载均衡的最大优势是便宜
  • 除了使用开源的系统进行负载均衡 ,如果业务 比较特殊, 也可能基于开源系统进行定制(例如, Nginx 插件),甚至进行自研。
    Nginx 的负载均衡架构
    计算高性能[集群高性能]_第2张图片

软件负载均衡的优缺点如下:

  • 简单:无论部署,还是维护都比较简单
  • 便宜:只要买个 Linux 服务器,装上软件即可
  • 灵活: 4层和7层负载均衡可以根据业务进行选择;也可以根绝业务进行比较方便的扩展,例如,可以通过 Nginx 的插件来实现业务的定制化功能
  • 性能一般 : 一个 Nginx 大约能支撑 5 万并发
  • 功能没有硬件负载均衡那么强大
  • 一般不具备防火墙和防 DDOS 攻击等安全功能

负载均衡架构

DNS 负载均衡、硬件负载均衡、软件负载均衡, 每种方式都有一些优缺点,但并不意味着在实际应用中只能基于它们的优缺点进行非此即彼的选择,反而是基于它们的优缺点进行组合使用 。 具体来说,组合的基本原则为 : DNS 负载均衡 用于实现地理级别的负载均衡;硬件负载均衡用于实现集群级别的负载均衡;软件负载均衡用于实现机器级别的负载均衡

计算高性能[集群高性能]_第3张图片

负载均衡算法

负载均衡算法数量较多,而且可以根据-些业务特性进行定制开发,抛开细节上的差异, 根据算法期望达到的目的,大体上可以分为如下几类:

  • 任务平分类 : 负载均衡系统将收到的任务平均分配给服务器进行处理,这里的“平均” 可以是绝对数量的平均,也可以是比例或权重上的平均
  • 负载均衡类 : 负载均衡系统根据服务器的负载来进行分配,这里的负载井不一定是通 常意义上我们说的接数、I/O使用率、网卡吞吐量等来衡量系统的压力
  • 性能最优类 : 负载均衡系统根据服务器的响应时间来进行任务分配,优先将新任务分配给响应最快的服务器
  • Hash类:负载均衡系统根据任务中的某些关键信息进行Hash运算,将相同Hash值的请求分配到同一台服务器上 。常见的有源地址Hash、目标地址hash 、session id hash 、用户id hash等

轮询

负载均衡系统收到请求后,按照顺序轮流分配到服务器上,轮询是最简单的一个策略,无须关注服务器本身的状态,例如:

  • 某个服务器当前因为触发了程序bug进入了死循环导致CPU负载很高,负载均衡系统是不感知的,还是会继续将请求源源不断地发送给它
  • 集群中有新的机器是32核的,老的机器是16核的,负载均衡系统也是不关注的,新老机器分配的任务数是一样的

需要注意的是负载均衡系统无须关注“服务器本身状态”,这里的关键词是“本身”。也就是说,只要服务器在运行,运行状态是不关注的,但如果服务器直接岩机了,或者服务器和负 载均衡系统断连了,则负载均衡系统是能够感知的,也需要做出相应的处理。例如,将服务器 从可分配服务器列表中删除,否则就会出现服务器都岩机了,任务还不断地分配给它,这明显 是不合理的。总而言之,“简单”是轮询算法的优点, 也是它的缺点

加权轮询

负载均衡系统根据服务器权重进行任务分配,这里的权重一般是根据硬件配置进行静态配置的,采用动态的方式计算会更加契合业务,但复杂度也会更高。加权轮询是轮询的一种特殊形式,其主要目的就是为了解决不同服务器处理能力有差异的问题 。 例如,集群中有新的机器是32核的,老的机器是16核的,那么理论上我们可以假设新机器的处理能力是老机器的2倍,负载均衡系统就可以按照 2 : 1 的比例分配更多的任务给新机 器,从而充分利用新机器的性能。

加权轮询解决了轮询算法中无法根据服务器的配置差异进行任务分配的问题,但同样存在 无法根据服务器的状态差异进行任务分配的问题 。

负载最低优先

负载均衡系统将任务分配给当前负载最低的服务器,这里的负载根据不同的任务类型和业 务场景,可以用不同的指标来衡量。例如:

  • LVS 这种 4 层网络负载均衡设备,可以以“连接数”来判断服务器的状态,服务器连接 数越大,表明服务器压力越大
  • Nginx这种 7 层网络负载系统,可以以“ HTTP 请求数”来判断服务器状态 CNginx 内 置的负载均衡算法不支持这种方式,需要进行扩展)
  • 如果我们自己开发负载均衡系统,可以根据业务特点来选择指标衡量系统压力 。 如果是 CPU 密集型,可以以“ CPU负载”来衡量系统压力:如果是 I/O 密集型 ,则可以以“IIO 负载”来衡量系统压力

负载最低优先的算法解决了轮询算法中无法感知服务器状态的问题,由此带来的代价是复 杂度要增加很多 。 例如:

  • 最少连接数优先的算法要求负载均衡系统统计每个服务器当前建立的连接,其应用场景仅限于负载均衡接收的任何连接请求都会转发给服务器进行处理,否则如果负载均衡系 统和服务器之间是固定的连接池方式,就不适合采取这种算法,例如,LVS 可以采取这 种算法进行负载均衡,而一个通过连接池的方式连接MySQL集群的负载均衡系统就不适合采取这种算法进行负载均衡。
  • CPU 负载最低优先的算法要求负载均衡系统以某种方式收集每个服务器的CPU负载, 而且要确定是以1分钟的负载为标准,还是以15分钟的负载为标准,不存在1分钟肯定比15分钟要好或差,不同业务最优的时间间隔是不一样的,时间间隔太短容易造成频繁波动,时间间隔太长又可能造成峰值来临时响应缓慢

负载最低优先算法基本上能够比较完美地解决轮询算法的缺点,因为采用这种算法后,负载均衡系统需要感知服务器当前的运行状态 。当然,其代价是复杂度大幅上升。通俗来讲,轮询可能是5行代码就能实现的算法,而负载最低优先算法可能要 1000 行才能实现,甚至需要负载均衡系统和服务器都要开发代码 。负载最低优先算法如果本身没有设计好,或者不适合业务的运行特点,算法本身就可能成为性能的瓶颈,或者引发很多莫名其妙的问题 。 所以负载最低优先算法虽然效果看起来很美好, 但实际上真正应用的场景反而没有轮询(包括加权轮询)那么多

性能最优类

负载最低优先类算法是站在服务器的角度来进行分配的,而性能最优优先类算法则是站在客户端的角度来进行分配的,优先将任务分配给处理速度最快的服务器,通过这种方式达到最 快响应客户端的目的 。
和负载最低优先类算法类似,性能最优优先类算法本质上也是感知了服务器的状态,只是 通过响应时间这个外部标准来衡量服务器状态而己。因此性能最优优先类算法存在 的问题和负 载最低优先类算法类似,复杂度都很高,主要体现在:

  • 负载均衡系统需要收集和分析每个服务器每个任务的响应时间,在大量任务处理的场景下,这种收集和统计本身也会消耗较多的性能
  • 为了减少这种统计上的消耗,可以采取采样的方式来统计,即不统计所有任务的响应时间, 而是抽样统计部分任务的响应时间来估算整体任务的响应时间,采样统计虽然能够减少性 能消耗,但使得复杂度进一步上升, 因为要确定合适的采样率,来样率太低会导致结果不准确,采样率太高会导致性能消耗较大,找到合适的来样率也是一件复杂的事情
  • 无论全部统计,还是采样统计,都需要选择合适的周期: 是10秒内性能最优,还是1分钟内性能最优 ,还是5分钟内性能最优……没有放之四海而皆准的周期,需要根据实际业务进行判断和选择, 这也是一件比较复杂的事情,甚至出现系统上线后需要不断地调优才能达到最优设计

Hash 类

负载均衡系统根据任务中的某些关键信息进行 Hash 运算,将相同 Hash 值的请求分配到同一台服务器上,这样做的目的主要是为了满足特定的业务需求。 例如:

  • 源地址 Hash
    将来源于同一个源IP地址的任务分配给同一个服务器进行处理,适合于存在事务、会话的业务。 例如,当我们通过浏览器登录网上银行时,会生成一个会话信息,这个会话是临时的, 关闭浏览器后就失效。网上银行后台无须持久化会话信息,只需要在某台服 务器上临时保存这个会话就可以了,但需要保证用户在会话存在期间,每次都能访问到同一个服务器,这种业务场景就可以用源地址 Hash 来实现
  • ID Hash
    将某个ID标识的业务分配到同一个服务器中进行处理,这里的ID一般是临时性数据的ID(例如 ,session id)例如,上述的网上银行登录的例子,用session id hash同样可以实现同一个会话期间,用户每次都是访问到同一台服务器的目的

你可能感兴趣的:(架构师养成记,DNS负载均衡,硬件负载均衡,软件负载均衡,负载均衡架构,负载均衡算法)