负载均衡集群-详解

Posted coderFan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了负载均衡集群-详解相关的知识,希望对你有一定的参考价值。

准备工作
前言

当伴随请求量剧增,超过单台服务器压力时,怎么办呢?有两种方式:

scale on:向上扩展,提供性能更好的机器。但是,往往机器的价钱和机器的性能并不是绝对成正比的。

scale out:向外扩展,提供更多的服务器来满足同一个需求,毕竟众人拾柴火焰高,因此引出集群的概念。

集群概念

将多台主机组织起来形成一个并行或分布式系统,来满足某一特定需求。

集群分类

集群根据用途不同,可以分为负载均衡集群、高可用集群以及高性能集群。

  1. 负载均衡集群

  • 负载均衡集群(LB,Load Balancing)的关键在于如何将计算任务合理的分摊到多台互联的服务器上。

  • 集群中的负载通常包括两类:计算任务处理负载(CPU)和网络I/O流量负载(I/O)。针对计算任务负载,负载均衡器能够使用同一组计算应用程序为大量用户提供服务,其中每个节点承担一部分任务来降低负载,而且节点间可以动态调整;而网络I/O流量负载,当网络服务程序接收到高入网流量而无法及时处理时,相关流量会被分发到其他服务器节点上,也是可以根据每个节点不同的可用资源或者网络环境进行优化。

  1. 高可用集群

  • 高可用集群强调,部分机器发生故障时,集群管理系统能够及时的发现故障并将由该部分承载的任务重新分派到其他正常工作的服务器(Active:活动服务器)上。其关键在于能够快速准确的对系统故障做出响应。因此,为了实现这一点,集群通常会在多台服务器上运行冗余节点和服务(Passive:备用服务器),并用来互相监控,例如通过心跳检测机制来弹指服务器的工作状态。若发生故障,那么备用节点将会顶替,对于用户而言,高可用集群永远不会down机。

  • 在高可用集群中,服务的可用性可以使用以下公式进行计算:可用性Availability = 在线时间/(在线时间+故障修复时间)。另外,在高可用集群中可能会遇到如下几个问题:

    • 如何判断服务是否在线呢?
      可以通过组播方式来相互通知。

    • 如何防止脑裂呢?
      首先脑裂(split-brain)是指多个节点之间状态出现歧义,导致互相抢占资源。此时,我们可以强行杀死,最简单的方式就是使对方关机或者直接切掉对方的电源(此方式也被称为STONITH)。另外,节点最好配置成奇数个,可以设置投票百分比,达到该阈值就认为对方主机服务不可用。

    • 鉴于此,LB集群和HA集群的区别如下几点:
      1) LB具备一定的高可用能力,主要是前端调度器,对后端主机具有一定的health check能力,但是后端服务器互相之间没有通信。但是HA集群有,因为HA集群对用户而言,服务永远可用,因此各个环节都需要进行健康检查。
      2) LB根本着眼点在于提高服务并发处理能力。HA根本着眼点在于提高服务的可用性

  1. 高性能计算集群

  • 高性能集群通常被用于承载计算密集型任务,而不是用于I/O密集型的应用场景。这类计算集群以并行和分布式计算为基础,对外而言好像是一台性能强大的超级计算机。

  • 比如双11淘宝或者京东的日志分析系统,需要根据数据计算出哪些区域属于消费热点区域,哪些商品属于热点商品等等。通常这类数据都是巨大的,要想快速计算获取结果,目前主要解决方案就是分布式处理,包括分布式计算和分布式存储。其中分布式计算:负责将任务进行切分,常见的如hadoop的MapReduce框架;分布式存储,是避免磁盘I/O成为性能瓶颈,毕竟单台机器的I/O性能有限,常见的如hadoop的hdfs。

集群优点
  • 提高性能:针对需要强大的计算处理能力才能完成的任务,单台服务器难以胜任,只能利用集群技术奖多态服务器的计算能力整合起来,通过并行计算获得超高的计算性能。

  • 降低成本:单台服务器为了获得较高性能,必须要在软硬件上具有足够的支撑能力,这极大提高了设计和制造成本。

  • 提高可扩展性:为满足计算需求动态变化,系统的可扩展性必须要被支持。单台服务器需要通过改变软硬件的配置才能改变自身具有能力,而集群只需调整集群中的网络节点数量即可做到集群规模及相关计算能力的缩放。(好吧,退一万步说:灰度测试也容易些吧);

  • 增强可用性:集群中的服务器可以在集群管理系统的统一管理下,实现不同服务器之间的负载均衡、容错备援等高可用机制。当部分服务器发生故障不能工作时,集群可以在很短时间的时间内完成故障切换,将故障服务器承担的任务转移到正常服务器上,减少故障损失。

负载均衡
架构

如上图所示,在这里暂不考虑负载均衡集群中调度器的主从设计,也不区分负载均衡器是以直连还是旁挂方式部署,目的是为了抽象出最简单的架构模型。
应用服务器集群通常设计成无状态的,即不存储请求上下文信息,这样保证用户请求发往任何一台服务器上得到结果一致。因此,当前端用户发出请求时,会通过网络(网络)传送至调度器,调度器根据已配置的`调度算法`,将请求转发至后台的服务集群(在这里APP表示各种应用服务,如web服务tomcat等),这些集群是真正提供服务的,如访问数据库、转发请求等。另一方面,调度器会定期对后台服务进行`健康检查`,以保证服务的可用性。
术语

Director:调度器,又称负载均衡器

RS:Real Server,后端真正工作的应用服务器

CIP:Client IP,客户端IP

VIP:Virtual IP,接受用户请求

RIP:Real Server IP,后台真正工作的主机IP

负载均衡算法

负载均衡集群-详解

负载均衡分类
  1. 不同参考指标分类

负载均衡集群-详解
补充:

  • 路由器:三层设备,基于目标IP进行分发的。

  1. 四层和七层区别

  • 安全性
    四层模式下,容易受到SYN攻击,而七层模式下,这些SYN攻击在负载均衡器上就可以实施拦截,此外由于七层模式直接处理应用层报文,通过设置多种策略,还可以过滤SQL注入等应用层面的特定攻击,安全性更高。

  • 性能与灵活性
    四层模式工作在内核,性能较七层更高,但七层灵活性更高。现在大型网站,常常会用七层模型如nginx来做反向代理,实现动静分离,然后后续再使用lvs做负载均衡,当然这样的规模算是相当大了。

负载均衡实现

负载均衡集群-详解

如上图所示,当用户通过浏览器发出请求时,首先流入HTTP重定向负载均衡服务器,他会根据调度算法选择后端的一个RS来提供服务,然后通过重定向将该IP返回给浏览器,浏览器自动重新请求,来访问新的服务器。

  • 优点:

    • 实现方便,逻辑简单。

  • 缺点:

    • 浏览器需两次请求服务器才能完成一次访问,性能较差;

    • 由于不同用户访问时间、页面深度不同,所以重定向服务器自身的处理能力有可能会成为瓶颈;

    • 故障处理较差,若后端服务器发生故障,http重定向服务器不能及时发现,导致将请求依旧转发至该后端服务,用户请求最终失败;

  • 使用HTPP302重定向,可能使搜索引擎判断为SEO作弊,降低搜索排名度。

  1. DNS负载均衡
    DNS内容也是相当多的,在这里不详细叙说其原理,如果有感兴趣的小伙伴,可以关注coderFan的后续 文章。

    负载均衡集群-详解

  • 优点:

    • 配置简单,将负载均衡工作交给DNS服务器来处理;

    • DNS支持基于地理位置的域名解析,可以加快用户访问速度,改善性能,比如我们常见的CDN技术;

  • 缺点:

    • DNS服务器无法了解后端每台服务器性能,导致负载均衡效果较差;

    • 故障处理能力弱,当我们发现某一台后端服务器发生故障时,即使我们立即将该服务器从域名解析中去除,但由于DNS服务器会有缓存,该IP仍然会在DNS中保留一段时间,那么就会导致一部分用户无法正常访问网站。虽然可以使用动态DNS,但负载均衡粒度太大,因此常常用在多级负载均衡的第一级。

  1. 反向代理负载均衡
    反向代理服务器位于RS之前的服务器,所有流向后端的请求都会经过反向代理服务器,服务器根据用户请求要么直接将结果返回给用户,要么将请求转发给后端RS,处理完成后再返回用户。

负载均衡集群-详解

  • 优点:

    • 隐藏后端服务器,调度者具有更高的控制权;

    • 故障转移能力强,反向代理可以快速移除故障节点;

    • 更灵活的负载均衡调度算法,可以实现真正意义上的负载均衡。

  • 缺点:

    • 调度器压力较大,因此本身需要做集群;

  1. 从Linux2.4内核开始,其内置的Netfilter(具体敬请关注后续的防火墙相关文章)模块在内核中维护着一些数据包过滤表,这些表包含了控制数据包过滤的规则。正常的数据包工作有三种路径:

    第一种流向:向内部转发,正常走向。PREROUTING(入栈) –> INPUT
    第二种流向:流出。OUTPUT –> POSTROUTING
    第三种走向:转发。PREROUTING –> FORWARD –> POSTROUTING
    而LVS一改常态,工作在INPUT链,强行修改报文走向。下图为LVS总体内核图:

负载均衡集群-详解

负载均衡集群-详解

  • 具体流程

    • 第一步:用户通过网络将请求发到调度器,调度器收到请求将其转发到内核空间,此时报文源IP为CIP,目标IP为VIP;

    • 第二步:PREROUTING链接收到请求,判断目标IP确定是不是本机IP,如果是将数据转发至INPUT链;

    • 第三步:LVS的IPVS模块会判断请求是否为已定义好的集群服务,如果是,则IPVS会强行修改数据包中的目标IP,并将报文转发至POSTROUTING链此时报文源IP为CIP,目标IP为RIP1;

    • 第四步:POSTROUTING链,收到报文发现目标IP刚好是自己的后端服务器,那么此时通过路径选择,将数据包发往后端的RS;

    • 第五步:后端的RS比对发现目标为自己IP,于是构建响应报文返回给Director Server。此时报文源IP为RIP1,目标IP为DIP;

    • 第六步:响应报文,走正常流程,即:POSTROUTING->FORWARD->PREROUTING,到Director,此时Director将源IP修改为VIP。此时响应报文源IP为VIP,目标IP为CIP。

  • 特点

    • RIP和DIP应该使用私有IP,RS网关必须要指向DIP(想想为什么)

    • 请求和响应报文都会经过Director,因此在极高并发环境下,Director可能会成为性能瓶颈;

    • 支持端口映射;

    • RS可以是任何OS,DS必须要是Linux,因为他要运行LVS;

    • RS的RIP必须要与Diector的DIP位于同一网络(想想这个又为啥呢)

    • RS的网关必须指向DIP。

4.1.2 lvs-fullnat模型
lvs-fullnat模型并不是lvs标准类型,其工作原理是同时改变报文的源IP和目标IP。因为,lvs的nat和dr类型要求调度器和RS距离不能太远,这样导致在部署时两者可能只能位于IDC,尤其是dr模型,要求两者必须要在同一物理网络,这显然局限性太大。而ip tunnel代价较高,要求中间的路由器和主机都要支持tunnel技术才行。

负载均衡集群-详解

  • 具体流程

    • 第一步:用户通过网络将请求发到调度器,调度器收到请求将其转发到内核空间,此时报文源IP为CIP,目标IP为VIP;

    • 第二步:PREROUTING链接收到请求,判断目标IP确定是不是本机IP,如果是将数据转发至INPUT链;

    • 第三步:LVS的IPVS模块会判断请求是否为已定义好的集群服务,如果是,则IPVS会强行修改数据包中的目标IP,并将报文转发至POSTROUTING链此时报文源IP为CIP,目标IP为RIP1;

    • 第四步:POSTROUTING链,收到报文发现目标IP刚好是自己的后端服务器,那么此时通过路径选择,将数据包发往后端的RS。此时报文源IP为DIP,目标IP为RIP1;

    • 第五步:由于调度器和RS不在同一个IDC,因此中间可能需要经过路由器,不过不要紧只要路由器能够记录映射关系即可,此时报文源IP为DIP,目标IP为RIP1;

    • 第六步:后端的RS比对发现目标为自己IP,于是构建响应报文返回给Director Server。此时报文源IP为RIP1,目标IP为DIP;

    • 第七步:响应报文,走正常流程,即:路由器-POSTROUTING->FORWARD->PREROUTING,到底Director,此时Director将源IP修改为VIP,目标IP修改为CIP。此时响应报文源IP为VIP,目标IP为CIP。

  • 特点

    • RIP和DIP使用私有IP,但是两者无需在同一机房,VIP必须要为公网IP;

    • 请求和响应报文都会经过Director,因此在极高并发环境下,Director可能会成为性能瓶颈;

    • 支持端口映射;

    • RS可以是任何OS。

4.2 LVS-TUN模型
纵使将LVS-TUN模型划分到这里略显牵强,不过好像没有其他更好的地方了,哈哈。
LVS-TUN模型和DR有点类似,但他的工作方式是:不修改请求报文的IP首部(源IP为CIP,目标IP为VIP),而是在原有的IP首部这外再次封装一个IP首部(源IP为DIP,目标IP为RIP)。

负载均衡集群-详解

  • 具体流程

    • 第一步:用户通过网络将请求发到调度器,调度器收到请求将其转发到内核空间,此时报文源IP为CIP,目标IP为VIP;

    • 第二步:PREROUTING链接收到请求,判断目标IP确定是不是本机IP,如果是将数据转发至INPUT链;

    • 第三步:LVS的IPVS模块会判断请求是否为已定义好的集群服务,如果是,则IPVS会在现有报文基础上再次封装一层IP报文,封装源IP为DIP,目标IP为RIP,并将报文转发至POSTROUTING链,此时报文源IP为CIP,目标IP为RIP1;

    • 第四步:POSTROUTING链,收到报文发现封装了两层IP,知道要进行隧道转发,那么此时通过路径选择,将数据包发往后端的RS。此时报文源IP为DIP,目标IP为RIP1;

    • 第五步:后端的RS接收到报文拆掉最外层的IP,发现里面还有一层,而且目标是自己的lo接口VIP,那么此时进行处理。处理完成后,通过lo接口将报文送给其他网卡,构建响应报文返回给客户端。此时报文源IP为VIP,目标IP为CIP;

    • 第六步:响应报文,不再走Director。此时响应报文源IP为VIP,目标IP为CIP。
      特点

    • RS的网关不能也不可能指向DIP;

    • 不支持端口映射;

    • 调度器有两个IP,VIP和DIP;RS也有两个IP,RIP和VIP;

    • RS的OS必须支持IP隧道功能,集群节点可以跨越互联网。

负载均衡集群-详解

  • 具体流程

    • 第二步:PREROUTING链接收到请求,判断目标IP确定是不是本机IP,如果是将数据转发至INPUT链;

    • 第四步:POSTROUTING链,收到报文发现目标IP刚好是自己的后端服务器,那么此时通过路径选择,将数据包发往后端的RS;

  • 特点

    • 解决方案:

    • 调度器和RS都有两个IP,即VIP和DIP。而针对RS上的VIP都相同,可能会问这样不会引起IP冲突吗?解决方案:可以利用IP别名,而且VIP是被隐藏起来的,不会暴露在网络上,因此他一般被配置在lo接口,他可以接受请求,但是出去的时候可以从其他接口出去,如eth0;

    • RS跟Director必须在同一物理网络中,不能通过路由器的隔离,因为他们要通过MAC交换;

    • 请求报文必须由Director调度,但响应报文必须不能经由Director,因此每个RS都有一个VIP;

    • 不支持端口映射;

    • RS的网关不能指向DIP,因为他不经过调度器了;

负载均衡状态维持

HTTP本身是无状态(stateless)的,但是负载均衡无法做到无状态。因为如果先前用户请求在下一次请求时被转发至新的服务器,而该服务器并没有该用户记录,这显然不应该出现的。例如,你在京东购物车添加了n个商品,刷新之后发现全都没有了,这是一种什么体验?
因此,负载均衡时,为了保证同一用户session会被分配到同一台机器上,常常采用以下三种技术:

  • Session绑定

  • Session集群

  • Session服务器


以上是关于负载均衡集群-详解的主要内容,如果未能解决你的问题,请参考以下文章

LVS负载均衡集群服务搭建详解

负载均衡集群-详解

LVS负载集群详解

图文详解 配置Nginx+Tomcat负载均衡动静分离集群

Nginx实现集群的负载均衡配置过程详解

LVS负载均衡集群服务搭建详解