目录
1. 集群
2. 分布式系统
3. 集群与分布式的比较
4.通俗的解释
集群
分布式系统
总结
LVS(Linux Virtual Server)简介
LVS专业术语
工作原理
LVS调度算法
静态调度算法
动态调度算法
ipvsadm脑图
NAT模式集群
LVS的配置
在LVS主机内打开内核路由策略
主机3:webserver2
在主机检测rs
下载ipvsadm
在主机上测试
DR模式部署
LVS网络配置
路由器网络配置
打开路由内核策略
客户端
web1
web2
LVS策略设定
防火墙mark标记解决调度问题
防火墙mark标记
实现方法:
在Director主机打标记
在Director主机基于标记定义集群服务:
LVS 持久链接(Session 会话问题解决)
集群与分布式系统概念
1. 集群
定义: 集群是由多台计算机组成的系统,这些计算机协同工作,以解决特定的问题或提供特定服务。
类型:
- 负载均衡 (Load Balancing, LB): 由多个主机组成,每台主机只承担一部分负载。负载均衡器根据负载情况将请求分配到不同的主机。
- 高可用 (High Availability, HA): 通过冗余配置避免单点故障 (SPOF),确保系统持续可用。
- 可扩展性: 可以通过增加更多主机来扩展系统的处理能力。
关键指标:
- MTBF (Mean Time Between Failures): 平均无故障时间。
- MTTR (Mean Time To Restoration): 平均恢复时间。
- 可用性 (A): 计算公式为 A=MTBFMTBF+MTTRA=MTBF+MTTRMTBF。常见的可用性水平有 99%、99.5%、99.9%、99.99%、99.999%。
2. 分布式系统
定义: 分布式系统将业务拆分为多个子业务或功能模块,这些模块在不同的服务器上运行,以提供服务或完成任务。
类型:
- 分布式存储: 例如 Ceph、GlusterFS、FastDFS 和 MogileFS。
- 分布式计算: 例如 Hadoop 和 Spark。
常见应用:
- 分布式应用: 将服务按功能拆分,使用微服务架构。
- 分布式静态资源: 静态资源存储在不同的存储集群中。
- 分布式数据和缓存: 使用 Key-Value 缓存系统。
- 分布式计算: 针对特定业务需求使用分布式计算框架。
3. 集群与分布式的比较
-
集群: 在多台服务器上部署同一业务系统,每台服务器的功能和数据一致。集群通过增加并行处理能力提高效率,主要依靠负载均衡器分配请求。如果一台服务器故障,其他服务器可以接管其任务。
-
分布式: 业务被拆分为多个子业务或功能,每台服务器负责不同的任务。分布式系统提高效率的方法是缩短单个任务的执行时间。如果某个节点出现故障,可能会导致对应的子业务失败。
4.通俗的解释
你的比喻很有趣,但可以稍微调整一下,以更准确地描述集群和分布式系统的特点:
集群
比喻: 银行的多个服务窗口
解释: 想象银行有多个服务窗口(1号窗口、2号窗口等),每个窗口提供相同的服务(例如办理存款、取款等)。这些窗口一起工作,以提高处理客户的效率。如果一个窗口(服务器)忙碌或者出现问题,其他窗口(服务器)可以继续工作,确保服务的连续性和提高处理速度。所有窗口(服务器)都处理相同类型的任务,通过增加窗口数量(服务器),银行能够处理更多的客户(请求)。
分布式系统
比喻: 搬家中的分工
解释: 想象你和你的朋友在搬家。你负责搬冰箱,另一个朋友负责搬电脑。虽然你们的目标都是完成搬家,但你们各自负责不同的任务。你们将工作分解成不同的部分,通过并行处理来提高整体搬家的效率。如果你负责搬冰箱时,另一个人同时负责搬其他物品,这样可以更快地完成整个搬家任务。每个人(节点)专注于不同的任务(子任务),但最终的目标是一样的,即完成搬家。
总结
-
集群: 比如银行的多个服务窗口,所有窗口提供相同的服务,关注的是通过增加相同类型的服务窗口来提高处理能力(吞吐量)。
-
分布式系统: 比如搬家时的任务分工,每个人负责不同的物品,关注的是通过任务分解和并行处理来提高整体工作效率(加速单个任务的完成)。
通过这两个比喻,可以清楚地看到集群关注的是增加相同类型服务的处理能力,而分布式系统关注的是通过任务分解和并行处理来提高处理效率。
LVS(Linux Virtual Server)简介
LVS(Linux Virtual Server)是一个由章文嵩博士发起的自由软件项目,提供高性能的负载均衡解决方案。LVS集成于Linux内核中,主要用于在多个后端服务器之间分发客户端请求,以实现高可用性和负载均衡。
LVS专业术语
- DR: Director(负载均衡器,分发器)
- VS: Virtual Server(负载均衡集群对外提供的IP+Port)
- RS: Real Server(后端请求处理服务器)
- CIP: Client IP(客户端访问的IP)
- VIP: Virtual IP(外网访问的虚拟IP)
- DIP: Director IP(负载均衡器IP)
- RIP: Real Server IP(后端服务器IP)
工作原理
LVS根据请求报文的目标IP和端口,将请求调度到后端的某个RS。调度的选择基于配置的算法,从而实现负载均衡。用户请求LVS的VIP,LVS根据转发方式和调度算法,将请求转发给后端服务器,后端服务器处理请求并将结果返回给用户。用户无法感知到具体的后端服务器。
访问流程:CIP <--> VIP == DIP <--> RIP
LVS调度算法
静态调度算法
- RR(Round Robin): 轮询调度,每个RS按顺序处理请求。适用于RS能力相近的场景。
- WRR(Weighted Round Robin): 加权轮询,根据RS的权重进行调度。性能差的RS被调度的次数较少。
- SH(Source Hashing): 源IP哈希,将来自同一IP的请求始终发送到同一个RS,实现会话绑定(session sticky)。
- DH(Destination Hashing): 目标地址哈希,将同一目标地址的请求始终发送到同一个RS,适用于正向代理缓存场景。
动态调度算法
- LC(Least Connections): 最少连接数,将请求发送到活动连接数最少的RS。适用于长连接应用。
- WLC(Weighted Least Connections): 权重最少连接数,根据RS的权重和连接数进行调度。
- SED(Shortest Expectation Delay): 短期待延迟,优先调度初始连接数较高的RS,但权重较低的RS可能在初期会接收更多请求。
- NQ(Never Queue): 第一轮均匀分配,之后使用SED算法。
- LBLC(Locality-Based Least Connections): 基于位置的最少连接数,将请求分配给负载较轻的RS,适用于正向代理。
- LBLCR(LBLC with Replication): 带复制功能的LBLC,解决LBLC负载不均衡的问题,通过将负载重的请求复制到负载轻的RS。
通过这些算法,LVS能够有效地在多台后端服务器之间分配负载,优化资源利用,提升系统的整体性能和可靠性。
ipvsadm脑图
NAT模式集群
环境准备
从RHEL9.4母机中克隆出三台主机
主机1:LVS
添加一张网卡eth1,网络设定为仅主机模式,原有的eth0网络为nat模式。
eht0:运行脚本设定网络eth0------ip为172.25.254.100、网关172.25.254.2 主机名lvs.xie.org
eht1:运行脚本设定网络eth1----ip为192.268.0.100、主机名lvs.xie.org。网卡配置文件删掉网关
LVS的配置
[root@LVS ~]# cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0
[ipv4]
address1=172.25.254.100/24,172.25.254.2
method=manual
dns=114.114.114.114;
[root@LVS ~]# cat /etc/NetworkManager/system-connections/eth1.nmconnection
[connection]
id=eth1
type=ethernet
interface-name=eth1
[ipv4]
address1=192.168.0.100/24
method=manual
[root@LVS ~]# nmcli connection reload
[root@LVS ~]# nmcli connection up eth0
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/3)
[root@LVS ~]# nmcli connection up eth1
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/4)
[root@LVS ~]#
在LVS主机内打开内核路由策略
[root@LVS ~]# sysctl -a | grep ip_forward
net.ipv4.ip_forward = 1
net.ipv4.ip_forward_update_priority = 1
net.ipv4.ip_forward_use_pmtu = 0
[root@LVS ~]# cat /etc/sysctl.conf
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
net.ipv4.ip_forward=1
主机2:web1
网络设定为eth0仅主机模式。运行脚本设定eth0、ip为192.168.0.10 主机名web1.xie.org ,修改网关为192.168.0.100
配置文件
[root@web1 ~]# cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0
[ipv4]
address1=192.168.0.10/24,192.168.0.100
method=manual
[root@web1 ~]# dnf install httpd -y
[root@web1 ~]# curl 192.168.0.10
web1
[root@web1 ~]# echo web1 > /www/html/index.html
[root@web1 ~]# systemctl restart httpd
主机3:webserver2
网络设定为eth0仅主机模式。运行脚本设定eth0、ip为192.168.0.20 主机名webserver2.xie.org ,修改网关为192.168.0.100
配置文件
[root@web2 ~]# cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0
[ipv4]
address1=192.168.0.20/24,192.168.0.100
method=manual
[root@web2 ~]# dnf install httpd -y
[root@web2 ~]# echo web1 > /www/html/index.html
[root@web2 ~]# systemctl restart httpd
在主机检测rs
[root@LVS ~]# curl 192.168.0.10
web1
[root@LVS ~]# curl 192.168.0.20
web2
下载ipvsadm
[root@LVS ~]# dnf install ipvsadm -y
[root@LVS ~]# ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.10:80 -m
[root@LVS ~]# ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.20:80 -m
Destination already exists
[root@LVS ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.254.100:80 rr
-> 192.168.0.10:80 Masq 1 0 0
-> 192.168.0.20:80 Masq 1 0 0
[root@LVS ~]# ipvsadm-save > /etc/sysconfig/ipvsadm
[root@LVS ~]# systemctl enable --now ipvsadm.service
Created symlink /etc/systemd/system/multi-user.target.wants/ipvsadm.service → /usr/lib/systemd/system/ipvsadm.service.
在主机上测试
[root@LVS ~]# for i in {1..10};do curl 172.25.254.100;done
web2
web1
web2
web1
web2
web1
web2
web1
web2
web1
以上步骤成功实现了负载均衡。测试中使用不同的 Web 服务内容只是为了更明显地观察实验结果。在实际企业环境中,服务内容通常是相同的。这样配置可以有效地分配负载,提升系统的可靠性和性能。
DR模式部署
环境准备
本次实验需要准备5台Linux虚拟机,分别作为client,router(路由器服务),lvs调度器,web1,web2.。其具体网卡,IP要求如下图表所示
LVS网络配置
[root@lvs ~]# cat /etc/NetworkManager/system-connections/eth1.nmconnection
[connection]
id=eth1
type=ethernet
interface-name=eth1
[ipv4]
address1=192.168.0.50/24,192.168.0.100
method=manual
[root@lvs ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.100 0.0.0.0 UG 100 0 0 eth1
192.168.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth1
路由器网络配置
#eth0网卡设定NAT模式 IP为172.25.254.100
#eth1网卡设定仅主机模式 IP为192.168.0.100
[root@router ~]# cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0
[ipv4]
address1=172.25.254.100/24,172.25.254.2
method=manual
dns=114.114.114.114;
[root@router ~]# cat /etc/NetworkManager/system-connections/eth1.nmconnection
[connection]
id=eth1
type=ethernet
interface-name=eth1
[ipv4]
address1=192.168.0.100/24
method=manual
[root@router ~]#
打开路由内核策略
[root@router ~]# sysctl -a | grep ip_forward
net.ipv4.ip_forward = 1
net.ipv4.ip_forward_update_priority = 1
net.ipv4.ip_forward_use_pmtu = 0
[root@router ~]# cat /etc/sysctl.conf
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
net.ipv4.ip_forward = 1
客户端
[root@client ~]# cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0
[ipv4]
address1=172.25.254.200/24,172.25.254.100
method=manual
[root@client ~]# nmcli connection reload
[root@client ~]# nmcli connection up eth0
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/5)
[root@client ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.25.254.100 0.0.0.0 UG 100 0 0 eth0
172.25.254.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
[root@client ~]#
web1
[root@web1 ~]# cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0
[ipv4]
address1=192.168.0.10/24,192.168.0.100
method=manual
[root@web1 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.100 0.0.0.0 UG 100 0 0 eth0
192.168.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
[root@web1 ~]#
web2
[root@web2 ~]# cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0
[ipv4]
address1=192.168.0.20/24,192.168.0.100
method=manual
[root@web2 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.100 0.0.0.0 UG 100 0 0 eth0
192.168.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
# 直接利用环回接口设定VIP
[root@lvs ~]# ip a a 192.168.0.200/32 dev lo
[root@webserver1 ~]# ip a a 192.168.0.200/32 dev lo
[root@webserver2 ~]# ip a a 192.168.0.200/32 dev lo
LVS策略设定
[root@lvs ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@lvs ~]# ipvsadm -A -t 192.168.0.200:80 -s wrr
[root@lvs ~]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10:80 -g -w 1
[root@lvs ~]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.20:80 -g -w 2
[root@lvs ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.200:80 wrr
-> 192.168.0.10:80 Route 1 0 0
-> 192.168.0.20:80 Route 2 0 0
[root@lvs ~]#
在客户端访问
[root@client ~]# for i in {1..10}
> do
> curl 192.168.0.200
> done
web2
web1
web2
web2
web1
web2
web2
web1
web2
web2
[root@client ~]#
防火墙mark标记解决调度问题
以 HTTP 和 HTTPS 为例,当我们在 Real Servers (RS) 上同时开放 80 和 443 端口时,默认情况下,这两个端口会被分开轮询。这意味着 HTTP 请求和 HTTPS 请求会独立地进行轮询,可能会导致轮询不一致的问题。
例如,如果第一次访问 HTTP (80 端口) 的请求被轮询到 RS1,那么下次访问 HTTPS (443 端口) 的请求仍有可能被轮询到 RS1。这种轮询错乱现象可能会影响负载均衡的效果。
# 在RS1和RS2中安装mod_ssl模块,让RS支持https,重启apache
[root@web1 ~]# yum install mod_ssl -y
[root@web1 ~]# systemctl restart httpd
[root@web2 ~]# yum install mod_ssl -y
[root@web2 ~]# systemctl restart httpd
#在lvs上测试以下 -k表示访问时忽略证书
[root@lvs ~]# curl -k https://192.168.0.10
web1
# 在LVS上添加对于443端口的策略
[root@lvs ~]# ipvsadm -A -t 192.168.0.200:443 -s rr
[root@lvs ~]# ipvsadm -a -t 192.168.0.200:443 -r 192.168.0.10:443 -g
[root@lvs ~]# ipvsadm -a -t 192.168.0.200:443 -r 192.168.0.20:443 -g
[root@lvs ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.200:80 wrr
-> 192.168.0.10:80 Route 1 0 0
-> 192.168.0.20:80 Route 2 0 0
TCP 192.168.0.200:443 rr
-> 192.168.0.10:443 Route 1 0 0
-> 192.168.0.20:443 Route 1 0 0
[root@lvs ~]#
在这种情况下,两个集群调度的主机相同会导致轮询错乱的问题。当客户端发起请求时,两个请求可能都被轮询到同一台主机上。我们期望的是第一个请求到达 web1
,第二个请求到达 web2
,以确保合理的负载分配。为了实现这一目标,我们可以使用 mark
标记来优化调度策略,通过对请求进行标记,确保请求在不同的 Real Servers 上进行轮询,从而避免上述问题。
[root@client ~]# curl 192.168.0.200;curl -k https://192.168.0.200
web2
web2
[root@client ~]# curl 192.168.0.200;curl -k https://192.168.0.200
web1
web1
防火墙mark标记
FWM:FireWall Mark
MARK target 可用于给特定的报文打标记 --set-mark value
其中:value 可为0xffff格式,表示十六进制数字借助于防火墙标记来分类报文,而后基于标记定义集群服务:可将多个不同的应用使用同一个集群服务进行调度
实现方法:
在Director主机打标记
iptables -t mangle -A PREROUTING -d $vip -p $proto -m multiport --dports
$portl,$port2,..-i MARK --set-mark NUMBER
在Director主机基于标记定义集群服务:
ipvsadm -A -f NUMBER [options]
# 清空策略
[root@lvs ~]# ipvsadm -C
[root@lvs ~]# iptables -t mangle -A PREROUTING -d 192.168.0.200 -p tcp -m multiport --dport 80,443 -j MARK --set-mark 66
[root@lvs ~]# iptables -t mangle -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
MARK tcp -- 0.0.0.0/0 192.168.0.200 multiport dports 80,443 MARK set 0x42
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
[root@lvs ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@lvs ~]# ipvsadm -A -f 66 -s rr
[root@lvs ~]# ipvsadm -a -f 66 -r 192.168.0.10 -g
[root@lvs ~]# ipvsadm -a -f 66 -r 192.168.0.20 -g
[root@lvs ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
FWM 66 rr
-> 192.168.0.10:0 Route 1 0 0
-> 192.168.0.20:0 Route 1 0 0
此时就能防止访问多个端口的时候访问到同一台主机,使这台主机压力过大的问题。把两个端口用标记捆绑到一起被视为同一个,然后访问标记开始轮询。
LVS 持久链接(Session 会话问题解决)
在我们客户的上网过程中,存在诸多情形需要与服务器进行交互,客户需要向服务器提交响应信息。倘若单纯地进行调度,会致使客户填写的表单丢失。为处理此问题,我们能够运用 sh 算法,然而 sh 算法相对简单直接,或许会引发调度不均衡的状况。
解决方案
在进行调度时,不论采用何种算法,只要是相同来源的数据包,我们就将其访问记录于内存之中,即把这个源的主机调度至特定的 RS 上。
若在短期内(默认为 360 秒),同源再次访问,我们依旧依据内存中的记录调度信息,将这个源的访问依旧调度至同一台 RS 上。
要是经过了较长时间(默认最长时间为 360 秒),同源访问再度来访,那么就会被调度至其他的 RS 上
ipvsadm -AlE -tlulf service-address [-s scheduler] [-p [timeout]]默认60秒
# 在lvs调度器中设定
[root@lvs ~]# ipvsadm -E -f 6666 -s rr -p [3000]
[root@lvs ~]# ipvsadm -LnC
测试
[root@client ~]# curl 192.168.0.200;curl -k https://192.168.0.200
web2
web1
[root@client ~]# curl 192.168.0.200;curl -k https://192.168.0.200
web2
web1
[root@client ~]# curl 192.168.0.200;curl -k https://192.168.0.200
web2
web1
[root@client ~]# curl 192.168.0.200;curl -k https://192.168.0.200
web2
web1
[root@client ~]# curl 192.168.0.200;curl -k https://192.168.0.200
web2
web1
问题完美解决