负载均衡-Nginx核心算法工作原理

Nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;Nginx可以作为一个HTTP服务器进行网站的发布处理,另外Nginx可以作为反向代理进行负载均衡的实现。

Nginx和LVS都是可以独立工作的,Keepalived作为检测机制,不但可以和Nginx、LVS集成也可以和其他软件集成形成高可用方案(例如可以和MySQL数据库集成、可以和Jetty服务器集成、还可以和自己写的程序集成)。

1、Nginx核心算法

img

一致性Hash算法是现代系统架构中的最关键算法之一,在分布式计算系统、分布式存储系统、数据分析等众多领域中广泛应用。针对这个系列的博文,在负载均衡层、业务通信层、数据存储层都会有他的身影。

hash算法的关键在于它能够根据不同的属性数据,生成一串不相同的hash值,并且能够将这个hash值转换为

img范围整数(即上图中的圆环)。

一台服务器的某个或者某一些属性当然也可以进行hash计算(通常是这个服务器的IP地址和开放端口),并且根据计算分布在这个圆环上的某一个点。也就是图中圆环上的蓝色点。

一个处理请求当然也可以根据这个请求的某一个或者某一些属性进行hash计算(可以是这个请求的IP、端口、cookie值、URL值或者请求时间等等),并且根据计算记过分布在这个圆环上的某一个点上。也就是上图圆环上的黄色点。

我们约定落在某一个蓝点A左侧和蓝点B右侧的黄色点所代表的请求,都有蓝点A所代表的服务器进行处理,这样就完成解决了“谁来处理”的问题。在蓝色点稳定存在的前提下,来自于同一个Hash约定的请求所落在的位置都是一样的,这就保证了服务处理映射的稳定性。

当某一个蓝色点由于某种原因下线,其所影响到的黄色点也是有限的。即下一次客户端的请求将由其他的蓝色点所代表的服务器进行处理。

2、轮询与加权轮询

img

当有任务需要传递到下层节点进行处理时,任务来源点会按照一个固定的顺序,将任务依次分配到下层节点,如果下层可用的节点数量为X,那么第N个任务的分配规则为:

目标节点=(NmodX)+1

轮询处理在很多架构思想中都有体现:DNS解析多IP时、LVS向下转发消息时、Nginx向下转发消息时、Zookeeper向计算节点分配任务时。了解基本的轮询过程有助于我们在进行软件架构设计时进行思想借鉴。但是上面的轮询方式是有缺陷的,由于各种客观原因我们可能无法保证任务处理节点的处理能力都是一样的(CPU、IO、内存频率等不同)。所以A节点业务能同时处理100个任务,但是B节点可能同时只能处理50个任务。在这种情况下我们需要依据下层节点某个或者多个属性设置权值。这个属性可能是网络带宽、CPU繁忙程度或者就是各一个固定的权值。

那么加权轮询的分配依据是什么呢?有很多分配依据,例如:概率算法(此算法中包括蒙特卡罗算法,拉斯维加斯算法和舍伍德算法,在网络上有很多介绍资料)、最大公约数法。这里我们对最大公约数算法进行介绍,因为该方法简单实用:

img

首先按照某种规则计算得到每个处理节点的权值,上文已经说到计算规则可能是这个服务节点的CPU利用率、网络占用情况或者在配置文件中的固定权重。

求这些权值的最大公约数,在上图中三个节点的权值分别是100、80、60.那么求得的最大公约数就是20(如果您忘记了最大公约数的定义,请自行复习)。那么这三个节点的被除结果分别是5、4、3,求和值为12。得到以上的计算结果,就可以开始进行请求分配了,公式同样为:

(NmodX)+1=Y

其中N表示当前的第N次任务;X表示整除后的求和结果;Y为处理节点。

备注:加权轮询是轮询方案的补充,通过将处理节点的属性转换成权值可以有效的描述处理节点的处理能力,实现更科学的处理任务分配。加权轮询的关键在于加权算法,最大公约数算法简单实用,定位效率高。

推荐文章