调度算法介绍
LVS 有两种类型的调度算法,其一就是静态的调度算法,这种算法一经实现,后续就不会发生变化,是既定的规则,后续数据包的流转都会按照这种规则进行按部就班的流转;其二就是动态的调度算法,这种算法是基于网络状况,或者后端服务器的状况,连接的状况等来进行实时的调整,算法的规则会根据实际情况而发生一定的变化。
静态调度算法
常用的静态调度算法有以下几种:
-
RR:轮叫调度(Round Robin)
调度器通过”轮叫”调度算法将外部请求按顺序轮流分配到集群中的真实服务器上,它均等地对待每一台服务器,而不管服务器上实际的连接数和系统负载。 -
WRR:加权轮叫(Weight RR)
调度器通过“加权轮叫”调度算法根据真实服务器的不同处理能力来调度访问请求。这样可以保证处理能力强的服务器处理更多的访问流量。 -
DH:目标地址散列调度(Destination Hash )
根据请求的目标 IP 地址,作为散列键(HashKey)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器。 -
SH:源地址 hash(Source Hash)
源地址散列”调度算法根据请求的源 IP 地址,作为散列键(HashKey)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器。
动态调度算法
-
LC:最少连接(Least Connections)
Overhead = Active * 256,调度器通过”最少连接”调度算法动态地将网络请求调度到已建立的链接数最少的服务器上。如果集群系统的真实服务器具有相近的系统性能,采用”最小连接”调度算法可以较好地均衡负载。 -
WLC:加权最少连接(Weighted Least Connections)
Overhead = (Active * 256) / weight,在集群系统中的服务器性能差异较大的情况下,调度器采用“加权最少链接”调度算法优化负载均衡性能,具有较高权值的服务器将承受较大比例的活动连接负载。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。 -
SED:最短延迟调度(Shortest Expected Delay)
Overhead = (Active + 1) * 256 / weight,在 WLC 基础上改进,不考虑非活动状态,Overhead 最小的,接受下次请求。 -
NQ:永不排队/最少队列调度(Never Queue Scheduling NQ)
无需队列。在遍历 RS 列表时,首先选择还没有任何活动连接的真实服务器。否则,选择负荷最小的真实服务器,每个真实服务器负荷的计算与 SED 调度器相同。 -
LBLC:基于本地最少连接数(Locality-Based Least-Connection)
LBLC 算法是基于 LC 算法的一个变种,其实是一种动态的 DH 算法,它会对 LC 算法调度的目的服务器进行缓存,对于后续的连接如果其目的 IP 可在缓存中找到目的服务器,使用其处理新连接。 -
LBLCR:带复制的 LBLC(Locality-based Least-Connection with Replication)
基于 LBLC 算法添加了缓存复制的功能,当两台服务器负载差距过于悬殊时,低负载的服务器会从高负载的服务器复制一部分目的缓存数据,后续此部分目的的连接将会请求到低负载的服务器。
ipvsadm 使用
ipvsadm
的使用情形分两类:
- 一是管理集群服务;
- 二是管理集群服务中的 RS;
首先我们需要定义出来的哪个协议的哪个端口用来代理集群服务,再对这个集群服务中的 RS 进行管理,每一类服务及服务中的 RS 都可进行增删查改操作。
其有如下特点:
- 一个 ipvs 主机可以同时定义多个 cluster service;
- 一个 cluster service 上至少有一个 real server;
定义时,要指明集群的 lvs-type(类型)以及 lvs scheduler(调度器)。
前面有说过 LVS 已经是标准内核的一部分,所以我们无需安装它,所以我们仅需要安装它的管理工具 ipvsadmin
,使用 yum 安装即可:
$ yum install ipvsadm -y
那下面说一下 ipvsadm
命令常用的使用规则吧~~
管理集群服务:
>: 下面 service-address 表示集群服务的地址。
增加和修改:
ipvsadm -A|E -t|u|f service-address [-s scheduler]
-A:增加;
-E:修改;
-t service-address:基于 tcp 协议,此时 service-address 为 ip:port;
-u service-address:基于 udp 协议,此时 service-address 为 ip:port;
-f service-address:基于 fwm(防火墙标记),此时 service-address 为一个数字,-f mark;
-s scheduler:指明调度算法,可选值参见文章开头的「调度算法介绍」,默认值为 wlc;
删除:
ipvsadm -D -t|u|f service-address
-D:删除;
-t|u|f:同增加和修改;
管理集群服务中的 RS:
>: 这里的 service-address 一定是已定义的,这里的重点是 server-address,它表示集群服务中 RS 的地址。
增加和修改:
ipvsadm -a|e -t|u|f service-address -r server-address
[-g|i|m] [-w weight] [-x upper] [-y lower]
-a:增加;
-e:修改;
-r server-address:指明 RS 的地址,格式为 -r ip[:port];
-g:gateway,dr 模型,也是默认值;
-i:ipip,tun 模型;
-m:masquerade,nat;
删除:
ipvsadm -d -t|u|f service-address -r server-address
管理集群服务或集群服务中的 RS(通用):
清空:
ipvsadm -C
查询:
ipvsadm -L|l [options]
-n:基于数字格式显示地址和端口;
-c:显示当前已建立的 IPVS 连接;
--stats:显示统计数据;
--rate:显示速率统计数据;
--exact:显示精确值,不做单位换算;
重载:
ipvsadm -R
保存:
ipvsadm -S [-n]
置零计数器:
ipvsadm -Z [-t|u|f service-address]
下面直接来构建实例演示一下 ipvsadm
命令的使用~~
构建集群实例
开始之前要确保几个主机中是不存在 iptables 规则的。
lvs-nat
首先需准备如下图三台测试主机:
其地址规划如图:
- Director 的 VIP 为
10.0.1.200
,内网地址 DIP 为172.16.1.200
; - RS1 的内网地址 RIP 为
172.16.1.201
; - RS2 的内网地址 RIP 为
172.16.1.202
;
1、给 Director 主机开启核心转发:
$ sysctl -w net.ipv4.ip_forward=1
2、设定 RS1 和 RS2 的默认网关为 Director 的内网地址 172.16.1.200
:
$ ip route add default via 172.16.1.200
$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.16.1.200 0.0.0.0 UG 0 0 0 eth0
3、配置 RS1 和 RS2 的 Web 服务,测试使用 Director 访问 RS1 和 RS2:
$ curl 172.16.1.201
<h1>test page on node2.zze.xyz</h1>
$ curl 172.16.1.202
<h1>test page on node3.zze.xyz</h1>
这里的 Web 服务就随便使用 httpd 或者 Nginx 啦,返回的内容能区分是不同 RS 返回即可。
4、添加使用 rr 算法的集群服务以及集群服务中的 RS:
$ ipvsadm -A -t 10.0.1.200:80 -s rr
$ ipvsadm -a -t 10.0.1.200:80 -r 172.16.1.201:80 -m
$ ipvsadm -a -t 10.0.1.200:80 -r 172.16.1.202:80 -m
5、测试使用浏览器访问 Director:
可以看到负载均衡的效果已经实现啦,并且是基于 lvs-nat 的 rr 轮询算法~~~
lvs-dr
这里假设 VIP、DIP 以及 RIP 都在同一个网段,规划主机如下:
说明:
- Director 和 RS 都处于同一个网络并且指向同一个网关;
- Director 的 VIP 以别名形式配置在它的 eth0 接口上;
- RS 的 VIP 以别名形式配置在它的 lo 接口上;
做下面操作之前需要同 lvs-nat 实例中启动 RS 的 Web 服务哦。
1、配置 Director 的 VIP:
$ ifconfig eth0:0 10.0.1.199/32 broadcast 10.0.1.199 up
VIP 仅作为 Director 被请求的目标地址,所以掩码给 32 位即可;
broadcast 10.0.1.199
设定只给自己广播,此项可选,目的是不主动干预网关的路由表;
2、设定两个 RS 的内核参数:
$ echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
$ echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
$ echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
$ echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce
关于这两个参数的使用说明可参考:『Linux内核参数之arp_ignore和arp_announce』。
3、给两个 RS 的本机回环接口上配置上 VIP:
$ ifconfig lo:0 10.0.1.199/32 broadcast 10.0.1.199 up
$ route add -host 10.0.1.199 dev lo:0
第二条路由配置可选,目的是让
10.0.1.199
作为本地回环地址使用,而不去请求外部主机;。
4、在客户端主机(宿主机)上 ping 一下 VIP,然后查看一下 ARP 表:
$ ping 10.0.1.199
PING 10.0.1.199 (10.0.1.199): 56 data bytes
64 bytes from 10.0.1.199: icmp_seq=0 ttl=64 time=0.405 ms
64 bytes from 10.0.1.199: icmp_seq=1 ttl=64 time=0.491 ms
^C
$ arp -a
? (10.0.1.199) at 0:c:29:ec:96:39 on vmnet2 ifscope [ethernet]
? (10.0.1.200) at 0:c:29:ec:96:39 on vmnet2 ifscope [ethernet]
可以看到给我们响应的 10.0.1.199
对应的 MAC 地址的确是 Director 主机,即两个配置了同样 VIP 的 RS 没有响应,说明我们给 RS 配置的内核参数是生效的。
5、添加 IPVS 规则:
$ ipvsadm -A -t 10.0.1.199:80 -s rr
$ ipvsadm -a -t 10.0.1.199:80 -r 10.0.1.201 -g
$ ipvsadm -a -t 10.0.1.199:80 -r 10.0.1.202 -g
6、测试使用浏览器访问 VIP:
可以看到负载均衡的效果已经实现啦,并且是基于 lvs-dr 的 rr 轮询算法~~~
其它操作
修改与删除规则
这里就以 lvs-nat 实例为基础演示一下集群服务以及集群服务中的 RS 的规则的修改与删除操作。
如果我们需要修改集群服务的调度算法为 sh,则可以使用 -E
选项了,如下:
$ ipvsadm -E -t 10.0.1.200:80 -s sh
我们已经知道 sh 算法是基于源地址哈希,所以我们现在使用同一个主机的浏览器访问 Director 肯定是一直返回同一个 RS 的页面,这里我就不做演示啦。
同理,如果我们需要修改集群服务中的 RS 的规则,则需要使用 -e
选项,下面以修改集群服务中 RS 的映射端口为 8080 为例:
$ ipvsadm -e -t 10.0.1.200:80 -r 172.16.1.201:8080 -m
$ ipvsadm -e -t 10.0.1.200:80 -r 172.16.1.202:8080 -m
我这里不知道为啥一直报错:
Memory allocation problem
。。。如果你也和我一样,那就直接修改/etc/sysconfig/ipvsadm
然后恢复,或者删了重新添加规则。
如果我们需要删除集群服务中的 RS2 则可使用 -d
选项,执行下面命令即可:
$ ipvsadm -d -t 10.0.1.200:80 -r 172.16.1.202:8080
如果要直接删除集群服务,使用 -D
选项即可,如下:
$ ipvsadm -D -t 10.0.1.200:80
保存与重载规则
执行 systemctl stop ipvsadm
时 ipvsadm 默认保存规则到 /etc/sysconfig/ipvsadm
。
而执行 systemctl start ipvsadm
时 ipvsadm 默认会从 /etc/sysconfig/ipvsadm
中恢复规则。
它们执行的命令可以在 /usr/lib/systemd/system/ipvsadm.service
中看到:
$ cat /usr/lib/systemd/system/ipvsadm.service
[Unit]
Description=Initialise the Linux Virtual Server
After=syslog.target network.target
[Service]
Type=oneshot
ExecStart=/bin/bash -c "exec /sbin/ipvsadm-restore < /etc/sysconfig/ipvsadm"
ExecStop=/bin/bash -c "exec /sbin/ipvsadm-save -n > /etc/sysconfig/ipvsadm"
ExecStop=/sbin/ipvsadm -C
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
当然我们也可以手动执行保存或重载操作。
下面命令用来保存当前规则到 /etc/sysconfig/ipvsadm
:
$ ipvsadm-save -n > /etc/sysconfig/ipvsadm
$ ipvsadm -S -n > /etc/sysconfig/ipvsadm
下面命令用来从 /etc/sysconfig/ipvsadm
中恢复规则:
$ ipvsadm-restore < /etc/sysconfig/ipvsadm
$ ipvsadm -R < /etc/sysconfig/ipvsadm
评论区