Lvs四层负载均衡和调度算法

lvs四层负载均衡

nat模式
后端服务器支持数量10-20台
使用最少两个网段
可以说是3层负载均衡

dr模式
后端服务器支持数量100+台
使用一个网段
可以说是2层负载均衡

隧道模式
后端服务器支持数量100左右
异地负载均衡 realserver必须使用公网Ip,还得需要服务器支持ip隧道协议

full-nat

↓↑↵→←↔

nat:数据流向从client-->dr--->rs rs-->dr--->client
client cip
↑↓
↑↓------->vip
dr
↑↓------->dip
-------------
↑↓ ↓
rs1 rs2----->rip

dr模式:流量从client-->dr-->rs rs-->client



→→→→→→ client cip 23
↑ ↓
↑ ↓------->vip 30
dr
↑ ↓------->dip 20
↑ +----------+
←←←←↓ ↓
rs1 rs2----->rip
21 22
设置vip30/32 设置vip30/32

路由数据包:源Ip不会发生变化 目标IP发生变化
源和目标MAC都会发生变化

23--->30
30--->23

1.来回数据包不一致
1)在rs的lo网卡设置vip/32
2)在rs上拒绝arp回应
3)设置让更好的IP回应数据包

2.在同一台机器上出现两块同一网段的网卡,数据包出去的时候,谁的路由条目在上面,就走哪块网卡

dr --- rs
s ip 23
d ip 30

s ip 30
d ip 23

信 要发给小明

#ipvsadm -A -t vip:80 -s rr
#ipvsadm -a -t vim:80 -r rip1:80 -g
#ipvsadm -a -t vim:80 -r rip2:80 -g

#echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
#echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

dr模式问题:
arp广播
1.9 ping 192.168.1.8

1. 客户端要找vip访问80端口,因为是在同一个网段,所以发arp广播找vip的mac地址通信
2. 因为有rs上也有vip,我们不能直接让rs上的vip回应客户端的广播,所以设置文件arp_ignore的内容为1
1的意思是如果发来的广播包里面目标地址不是我的“进口地址”-->也就是“eth0”(对应的是非进口地址本地回环接口lo),那我就不回应这个arp广播)。
3. 当dr的vip收到这个广播之后,回应mac地址,然后得到客户端发来的80端口请求,再通过lvs分发到一个rs
4. 那么dr如何分发到一个rs?
dip发出arp广播询问rs的ip地址所对应的mac地址,然后发出一个目标ip为rs_vip,目标mac为rs_eth0_mac的包到rs
5. 这个rs必须要使用他lo设置的vip把回应包发出去(这样client收到之后一看源地址是vip,他就会相信这是正确的地址发来的包)
6. 那么怎样让rs使用lo的vip而不使用eth0?
设置arp_announce文件的内容为2, 2的意思是使用本机最好的本地IP地址把回应包发出去
7. 最后怎么算是最好的本地IP地址?
同一个网段下,使用可变长度子网掩码最长的IP地址被认为是好IP,因为他更精确

dr模式


数据链路层负载均衡
顾名思义,数据链路层负载均衡是指在通信协议的数据链路层修改mac地址进行负载均衡。
这种数据传输方式又称作三角传输模式,负载均衡数据分发过程中不修改IP地址,只修改目的mac地址,通过配置真实物理服务器集群所有机器虚拟IP和负载均衡服务器IP地址一致,从而达到不修改数据包的源地址和目的地址就可以进行数据分发的目的,由于实际处理请求的真实物理服务器IP和数据请求目的IP一致,不需要通过负载均衡服务器进行地址转换,可将相应数据包直接返回给用户浏览器,避免负载均衡服务器网卡带宽成为瓶颈。这种负载均衡方式又称作直接路由方式(DR)。

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

3台机器
10.0.0.20 dr1 负载均衡器
10.0.0.21 rs1 web1
10.0.0.22 rs2 web2

1.两个rs上部署web服务
#yum install nginx -y
修改主机内容
启动服务:
#systemctl start nginx

2. 给两个web服务器的lo网卡设置子网掩码为32位vip
rs1:
# ifconfig lo:0 10.0.0.30/32
rs2:
# ifconfig lo:0 10.0.0.30/32

3.给两个web服务器设置内核参数
为了让vip发包出去
# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

忽略arp响应
# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore

4.保证dr这台机器数据包是从dip发出去的
如何判断:两块网卡
谁的路由条目在上面,谁就是dip,另一个就是vip

5.在dr上设置lvs路由条目
# yum install ipvsadm -y
# ipvsadm -A -t 10.0.0.30:80 -s rr
# ipvsadm -a -t 10.0.0.30:80 -r 10.0.0.21:80 -g
# ipvsadm -a -t 10.0.0.30:80 -r 10.0.0.22:80 -g


-A 添加virtual server
-t 指定使用tcp协议
-s 指定调度策略为rr
-a 添加realserver
-r 指定realserver是谁


让配置永久生效:
# ipvsadm-save > /etc/sysconfig/ipvsadm
# systemctl enable ipvsadm


命令选项解释:

-A --add-service 在内核的虚拟服务器表中添加一条新的虚拟服务器记录。也就是增加一台新的虚拟服务器。
-E --edit-service 编辑内核虚拟服务器表中的一条虚拟服务器记录。
-D --delete-service 删除内核虚拟服务器表中的一条虚拟服务器记录。
-C --clear 清除内核虚拟服务器表中的所有记录。
-R --restore 恢复虚拟服务器规则
-S --save 保存虚拟服务器规则,输出为-R 选项可读的格式
-a --add-server 在内核虚拟服务器表的一条记录里添加一条新的真实服务器记录。也就是在一个虚拟服务器中增加一台新的真实服务器
-e --edit-server 编辑一条虚拟服务器记录中的某条真实服务器记录
-d --delete-server 删除一条虚拟服务器记录中的某条真实服务器记录
-L|-l --list 显示内核虚拟服务器表
-Z --zero 虚拟服务表计数器清零(清空当前的连接数量等)
--set tcp tcpfin udp 设置连接超时值
--start-daemon 启动同步守护进程。他后面可以是master 或backup,用来说明LVS Router 是master 或是backup。在这个功能上也可以采用keepalived 的VRRP 功能。
--stop-daemon 停止同步守护进程
-h --help 显示帮助信息
-p --persistent [timeout] 持久稳固的服务(持久性连接)。这个选项的意思是来自同一个客户的多次请求,将被同一台真实的服务器处理。timeout 的默认值为300 秒。
-t --tcp-service service-address 说明虚拟服务器提供的是tcp 的服务[vip:port] or [real-server-ip:port]
-f --fwmark-service fwmark 说明是经过iptables 标记过的服务类型。
-u --udp-service service-address 说明虚拟服务器提供的是udp 的服务[vip:port] or [real-server-ip:port]

-s --scheduler scheduler 使用的调度算法,有这样几个选项 rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,默认的调度算法是: wlc.

-M --netmask netmask persistent granularity mask
-r --real-server server-address 真实的服务器[Real-Server:port]
-g --gatewaying 指定LVS 的工作模式为直接路由模式(也是LVS 默认的模式)
-i --ipip 指定LVS 的工作模式为隧道模式
-m --masquerading 指定LVS 的工作模式为NAT 模式
-w --weight weight 真实服务器的权值
--mcast-interface interface 指定组播的同步接口
-c --connection 显示LVS 目前的连接 如:ipvsadm -L -c
--timeout 显示tcp tcpfin udp 的timeout 值 如:ipvsadm -L --timeout
--daemotcpdump -i ens33 tcp and port 80 -v -nnn 显示同步守护进程状态
--stats 显示统计信息
--rate 显示速率信息
--sort 对虚拟服务器和真实服务器排序输出
-n --numeric 输出IP地址和端口的数字形式

抓包:
#tcpdump -i ens33 tcp and port 80 -v -nn
-i 指定网卡
tcp 抓tcp协议的数据包
port 指定要抓哪个端口的包
-v 显示详细信息
-nn 以数字的形式显示ip和端口


--------------------
查看
#ip a
#ip a l dev ens33
添加IP:
# ip a a 192.168.1.8/24 dev ens33
删除IP:
# ip a d 192.168.1.8/24 dev ens33

#ifconfig
#ifconfig ens33
#ifconfig ens33 192.168.1.8

#ifconfig ens33:0 192.168.1.9
 

LVS调度算法

=================================================================================
1. 轮询调度(Round Robin)(简称rr)
调度器通过“轮叫”调度算法将外部请求按顺序轮流分配到集群中的真实服务器上,它均等地对待每一台服务器,而不管服务器上实际的连接数和系统负载。

2. 加权轮询(Weighted Round Robin)(简称wrr)
调度器通过“加权轮叫”调度算法根据真实服务器的不同处理能力来调度访问请求。这样可以保证处理能力强的服务器能处理更多的访问流量。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。

3. 最少链接(Least Connections)(LC)
调度器通过“最少连接”调度算法动态地将网络请求调度到已建立的链接数最少的服务器上。如果集群系统的真实服务器具有相近的系统性能,采用 “最小连接” 调度算法可以较好地均衡负载。

4.加权最少链接(Weighted Least Connections)(WLC)
在集群系统中的服务器性能差异较大的情况下,调度器采用“加权最少链接”调度算法优化负载均衡性能,具有较高权值的服务器将承受较大比例的活动连接负
载。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。

5. 基于局部性的最少链接(Locality-Based Least Connections)(LBLC)
“基于局部性的最少链接”调度算法是针对目标IP地址的负载均衡,目前主要用于Cache集群系统,因为在Cache集群中客户请求报文的目标IP地址是变化的。该算法根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则用“最少链接” 的原则选出一个可用的服务器,将请求发送到该服务器。


A B C D E A1 B1 C1 D1 E1 A2 B2 C2 D2 E2
1
2
3

6. 带复制的基于局部性最少链接(Locality-Based Least Connections with Replication)(LBLCR)
“带复制的基于局部性最少链接”调度算法也是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。它与LBLC算法的不同之处是它要维护从一个目标
IP地址到一组服务器的映射,而LBLC算法维护从一个目标IP地址到一台服务器的映射。该算法根据请求的目标IP地址找出该目标IP地址对应的服务器组,按
“最小连接”原则从服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器;若服务器超载,则按“最小连接”原则从这个集群中选出一台
服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复
制的程度。

7. 最短的期望的延迟(Shortest Expected Delay Scheduling SED)(SED)
基于wlc算法。这个必须举例来说了

A B C
1 2 3
1 2 3



ABC三台机器分别权重123 ,连接数也分别是123。那么如果使用WLC算法的话一个新请求进入时它可能会分给ABC中的任意一个。使用sed算法后会进行这样一个运算
A(1+1)/1
B(1+2)/2
C(1+3)/3
根据运算结果,把连接交给C。
注:前面的1是给所有连接数加1,后面的除数是权重
我本来负载就小,所以才连接数少,假如我这点负载再添加一个连接,我可能就挂了,但是你负载高的再添加1个连接,挂的可能小就比较小

8.最少队列调度(Never Queue Scheduling NQ)(NQ)
无需队列。如果有台 realserver的连接数=0就直接分配过去,不需要在进行sed运算

9. 目标地址散列(Destination Hashing)(DH) 特点是查找速度快
“目标地址散列”调度算法根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。

10. 源地址散列(Source Hashing)(SH)
“源地址散列”调度算法根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。
=================================================================================
外翻:
目标地址散列调度(Destination Hashing Scheduling)算法
是针对目标IP地址的负载均衡,但它是一种静态映射算法,通过一个散列(Hash)函数将一个目标IP地址映射到一台服务器。
目标地址散列调度算法先根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。该算法的流程如下:
目标地址散列调度算法流程

假设有一组服务器S = {S0, S1, ..., Sn-1},W(Si)表示服务器Si的权值,
C(Si)表示服务器Si的当前连接数。ServerNode[]是一个有256个桶(Bucket)的
Hash表,一般来说服务器的数目会小于256,当然表的大小也是可以调整的。
算法的初始化是将所有服务器顺序、循环地放置到ServerNode表中。若服务器的
连接数目大于2倍的权值,则表示服务器已超载。

n = ServerNode[hashkey(dest_ip)];
if ((n is dead) OR
(W(n) == 0) OR
(C(n) > 2*W(n))) then
return NULL;
return n;
在实现时,我们采用素数乘法Hash函数,通过乘以素数使得散列键值尽可能地达到较均匀的分布。所采用的素数乘法Hash函数如下:
素数乘法Hash函数

static inline unsigned hashkey(unsigned int dest_ip)
{
return (dest_ip* 2654435761UL) & HASH_TAB_MASK;
}
其中,2654435761UL是2到2^32 (4294967296)间接近于黄金分割的素数,
(sqrt(5) - 1) / 2 = 0.618033989
2654435761 / 4294967296 = 0.618033987


源地址散列调度(Source Hashing Scheduling)算法正好与目标地址散列调度算法相反,它根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。它采用的散列函数与目标地址散列调度算法 的相同。它的算法流程与目标地址散列调度算法的基本相似,除了将请求的目标IP地址换成请求的源IP地址,所以这里不一一叙述。
在实际应用中,源地址散列调度和目标地址散列调度可以结合使用在防火墙集群中,它们可以保证整个系统的唯一出入口。

=====================================
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。
 

猜你喜欢

转载自blog.csdn.net/qq_30429153/article/details/85259182