负载均衡算法与方案

220 阅读10分钟

前言

负载均衡学习记录 ~

负载均衡器

可以是专用设备,也可以是在通用服务器上运行的应用程序。 分散请求到拥有相同内容或提供相同服务的服务器。 专用设备一般只有以太网接口,可以说是多层交换机的一种。 负载均衡器一般会被分配虚拟IP地址,所有来自客户端的请求都是针对虚拟IP地址完成的。负载均衡器通过负载均衡算法将来自客户端的请求转发到服务器的实际IP地址上

负载均衡算法

const serverMap = new Map([    ['192.168.1.100', 1],
    ['192.168.1.101', 3],
    ['192.168.1.102', 1],
    ['192.168.1.103', 1],
    ['192.168.1.104', 4],
    ['192.168.1.105', 1],
    ['192.168.1.106', 2],
    ['192.168.1.107', 1],
    ['192.168.1.108', 1],
    ['192.168.1.109', 2],
    ['192.168.1.110', 1],
])

随机算法

Random

随机,按权重设置随机概率,在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整权重。

function random() {
    const servers = [];
    for (let [address, weight] of serverMap) {
        servers.push(address)
    }
    const index = Math.floor(Math.random() * servers.length);
    const address = address[index];
    console.log(address);
}

WeightRandom

按照权重

function weightRandom() {
    const servers = [];
    for (let [address, weight] of serverMap) {
        for (let i = 0; i < weight; i += 1) {
            servers.push(address)
        }
    }
    const index = Math.floor(Math.random() * servers.length);
    const address = address[index];
    console.log(address);
}

轮询及加权轮询

轮询(Round Robbin)

当服务器群中各服务器的处理能力相同时,且每笔业务处理量差异不大时,最适合使用这种算法。

轮询,按照公约后的权重设置轮询比率,存在慢的服务器累计请求问题,比如:第二台机器很慢,但没有挂,当请求调到第二台时就卡在那里,久而久之,所有请求都卡在第二台上。

const index = 0;
const servers = [];
for (let [address, weight] of serverMap) {
    servers.push(address)
}
// 循环取
function roundRobin() {
    if (index >= servers.length)  index = 0;
    console.log(servers[index]);
}

加权轮询(Weighted Round Robbin)

为轮询中的媚态服务器附加一定的权重算法,比如:

[服务器1, 权重]、[服务器2, 权重2]、[服务器3, 权重3]

则顺序为: 1 -> 2 -> 2 -> 3 -> 3 -> 3 -> 1 -> 2 -> 2 -> 3 -> 3 -> ...

const servers = [];
for (let [address, weight] of serverMap) {
    for (let i = 0; i < weight; i += 1) {
        servers.push(address)
    }
}
function weightRoundRobin() {
    // 循环取
    if (index >= servers.length)  index = 0;
    console.log(servers[index]);
}

最小连接及加权最小链接

最少连接(Least Connections)

在多个服务器中,与处理连接数(会话数)最少的服务器进行通信的算法,即使在每台服务器处理能力各不相同,每笔业务处理量也不相同的情况下,也能够在一定程度上降低服务器的负载。

加权最少连接(Weighted Least Connection)

为最少连接算法中的每一台服务器附加权重的算法,该算法事先为每台服务器分配处理连接的数量,并将客服端请求转至连接数最少的服务器上。

哈希算法

普通哈希

/**
 * remoteIp 为访问者
 */
function hash(remoteIp = '192.168.2.215') {
    const servers = [];
    for (let [address, weight] of serverMap) {
        servers.push(address)
    }
    const hashCode = remoteIp.hashCode(); // 进行哈希算法获取哈希值
    const index = hashCode % servers.length; // 进行 mod 运算
    console.log(servers[index]);
}

一致性哈希

一致性 Hash,相同参数的请求总是发到同一服务器上处理,当某一台服务器挂时,原本发往该服务器的请求,基于虚拟节点,平摊到其他服务器上,不会引起剧烈变动。

IP 地址散列

通过管理发送方 IP 和目的地 IP 地址的散列,将来自统一发送方的分组(或发送至统一目的地的分组)统一转到相同服务器的算法,当客户端由一系列业务需要处理而必须和一个服务器反复通信时,该算法能够以流(会话)为单位,保证来自相同客户端的通信能够一直在统一服务器中进行处理。

URL 散列

通过管理客户端请求 URL 信息的散列,将发送至相同 URL 的请求转发至同一服务器的算法。

负载均匀算法的手法

手法:

DNS -> 数据链路层 -> IP 层 -> Http 层

DNS 域名解析负载均衡(延迟)

image

利用 DNS 处理域名解析请求的同时进行负载均衡是一种常用的方案,在 DNS 服务器中配置多个 A 记录。

例如:

每次域名解析请求都会根据均衡负载算法计算一个不同的IP地址返回,这样 A 记录中配置的多个服务器就构成一个集群,并可以实现负载均衡。

DNS 域名解析负载均衡的优点是将负载均衡工作交给 DNS ,省略掉网络管理的麻烦,缺点就是 DNS 可能缓存 A 记录,不受网站控制。

事实上,大型网站总是部分使用 DNS 域名解析,作为第一级负载均衡手段,然后在内部做第二级负载均衡。

数据链路层负载均衡(LVS)

image

数据链路层负载均衡是指在通信协议的数据链路层修改 mac 地址进行负载均衡。

这种数据传输方式又称作“三角传输模式”,负载均衡数据分发过程中不修改 IP 地址,只修改目的地 mac 地址,通过配置真实物理服务器集群所有机器虚拟 IP 和负载均衡服务器 IP 地址一样,从而达到负载均衡,这样负载均衡方式又称为直接路由方式(DR)。

在上图中,用户请求到达负载均衡服务器后,负载均衡服务器将请求数据的目的 mac 地址修改为真实 WEB 服务器的 mac 地址,并不修改数据包目标 IP 地址,因此数据可以正常到达目标 WEB 服务器,该服务器在处理完数据后可以经过网管服务器而不是负载均衡服务器直接到达用户游览器。

使用“三角传输模式”的链路层负载均衡是目前大型网站所使用的最广的一种负载均衡手段,在 linux 平台上最好的数据链路层负载均衡开源产品是 LVS (linux vitual server)。

IP 负载均衡(SNAT)

image

IP 负载均衡:即在网络层通过修改请求目标地址进行负载均衡。

用户请求数据包到达负载均衡服务器后,负载均衡服务器在操作系统内核进行获取网络数据包,根据负载均衡算法计算得到一台真实的 WEB 服务器地址,然后将数据包的 IP 地址修改为真实的 WEB 服务器地址,不需要通过用户进程处理,真是的 WEB 服务器处理完毕后,响应数据包回到负载均衡服务器,负载均衡服务器再将数据包源地址修改为自身的 IP 地址发送给用户游览器。

这里的关键在于真实 WEB 服务器响应数据包如何返回给负载均衡服务器:

  • 一种是负载均衡服务器在修改目的 IP 地址的同时修改源地址,将数据包源地址改为自身的 IP,即原地址转换(SNAT)。
  • 另一种方案是将负载均衡服务器同时作为真实物理服务器的网关服务器,这样所有的数据都会到达负载均衡服务器。

IP 负载均衡在内核进程完成数据分发,较反向代理均衡有更改的处理性能,但由于所有请求数据的数据包都需要经过负载均衡服务器,因此负载均衡的网卡贷款成为系统的瓶颈,

HTTP 重定向负载均衡(少见)

image

HTTP 重定向服务器是一台普通的应用服务器,其唯一的功能就是根据用户的 HTTP 请求计算一台真实服务器地址,并将真实的服务器地址写入 HTTP 重定向响应中(响应状态码)返回给游览器,然后游览器在自动请求真实的服务器。

这种负载均衡方案的优点是比较简单,确定是游览器需要每次请求两次服务期才能完成一次访问,性能较差,使用 HTTP 302 响应码重定向,可能会被搜索引擎判断为 SE0 作弊,降低搜索排名。重定向服务器自身的处理能力有可能成为瓶颈,因此这种方案在实际使用中并不多见。

反向代理负载均衡(nginx)

image

传统代理服务器位于游览器一端,代理游览器将 HTTP 请求大送到互联网上。,而反向代理服务器则位于网站机房一侧,代理网站 web 服务器接收 http 请求。

方向代理的作用是保护网站安全,所有互联网的请求都是经过代理服务器没相当于在 web 服务器和可能的网络攻击之间建立了一个屏障。

除此之外,代理服务器也可以配置缓存加速 web 请求,当用户第一次访问静态内容的时候,静态内存就被缓存在方向代理服务器上,这样当其他用户访问该静态内容时,就可以直接从方向里服务器返回,加速 web 请求响应速度,减轻 web 服务器负载压力。

另外,反向代理服务器也可以实现负载均衡的功能。

image

由于反向代理服务器转发请求在 HTTP 协议层面,因此也叫应用层负载均衡,优点是部署简单,确定是可能成为系统的瓶颈。

参考文献