码迷,mamicode.com
首页 > 系统相关 > 详细

Linux负载均衡概念与实践(一)

时间:2015-11-04 17:43:12      阅读:277      评论:0      收藏:0      [点我收藏+]

标签:

根据网上文章整理。

负载均衡软件LVS(Linux Virtual Server)概念篇

lvs是在linux操作系统基础上建立虚拟服务器,实现服务节点之间的负载均衡。它是基于linux内核实现的。2.6.X内核默认集成了lvs模块。

lvs常用负载均衡的实现是基于ip协议的,所以一般称为ipvs。

IPVS基本上是一种高效的Layer-4交换机,它提供负载平衡的功能。当一个TCP连接的初始SYN报文到达时,IPVS就选择一台服务器,将报文转发给它。此后通过查发报文的IP和TCP报文头地址,保证此连接的后继报文被转发到相同的服务器。这样,IPVS无法检查到请求的内容再选择服务器,这就要求后端的服务器组是提供相同的服务,不管请求被送到哪一台服务器,返回结果都应该是一样的。但是在有一些应用中后端的服务器可能功能不一,有的是提供HTML文档的Web服务器,有的是提供图片的Web服务器,有的是提供CGI的Web服务器。这时,就需要基于内容请求分发 (Content-Based Request Distribution),同时基于内容请求分发可以提高后端服务器上访问的局部性。

IPVS是LVS集群系统的核心软件,它的主要作用是:安装在Director Server上,同时>在Director Server上虚拟出一个IP地址,用户必须通过这个虚拟的IP地址访问服务。 这个虚拟IP一般称为LVS的VIP,即Virtual IP。访问的请求首先经过VIP到达负载调度器,然后由负载调度器从Real Server列表中选取一个服务节点响应用户的请求。

使用LVS技术要达到的目标是:通过LVS提供的负载均衡技术和Linux操作系统实现一个高性能、高可用的服务器群集,它具有良好可靠性、可扩展性和可操作性。从而以低廉的成本实现最优的服务性能.

体系结构:

使用LVS架设的服务器集群系统有三个部分组成:最前端的负载均衡层,用Load Balancer表示,中间的服务器群组层,用Server Array表示,最底端的数据共享存储层,用Shared Storage表示,在用户看来,所有的内部应用都是透明的,用户只是在使用一个虚拟服务器提供的高性能服务。

LVS组成部分详细介绍:

? Load Balancer层:位于整个集群系统的最前端,有一台或者多台负载调度器(Director Server)组成,LVS模块就安装在Director Server上,而Director的主要作用类似于一个路由器,它含有完成LVS功能所设定的路由表,通过这些路由表把用户的请求分发给Server Array层的应用服务器(Real Server)上。同时,在Director Server上还要安装对Real Server服务的监控模块Ldirectord,此模块用于监测各个Real Server服务的健康状况。在Real Server不可用时把它从LVS路由表中剔除,恢复时重新加入。

? Server Array层:由一组实际运行应用服务的机器组成,Real Server可以是WEB服务器、MAIL服务器、FTP服务器、DNS服务器、视频服务器中的一个或者多个,每个Real Server之间通过高速的LAN或分布在各地的WAN相连接。在实际的应用中,Director Server也可以同时兼任Real Server的角色。

? Shared Storage层:是为所有Real Server提供共享存储空间和内容一致性的存储区域,在物理上,一般有磁盘阵列设备组成,为了提供内容的一致性,一般可以通过NFS网络文件系统共享数据,但是NFS在繁忙的业务系统中,性能并不是很好,此时可以采用集群文件系统,例如Red hat的GFS文件系统,oracle提供的OCFS2文件系统等。

从整个LVS结构可以看出,Director Server是整个LVS的核心,目前,用于Director Server的操作系统只能是Linux和FreeBSD,linux2.6内核不用任何设置就可以支持LVS功能,而FreeBSD作为Director Server的应用还不是很多,性能也不是很好。 对于Real Server,几乎可以是所有的系统平台,Linux、windows、Solaris、AIX、BSD系列都能很好的支持。

负载均衡与负载调度算法

1.IP负载均衡技术 负载均衡技术有很多实现方案,有基于DNS域名轮流解析的方法、有基于客户端调度访问的方法、有基于应用层系统负载的调度方法,还有基于IP地址的调度方法,在这些负载调度算法中,执行效率最高的是IP负载均衡技术。

LVS的IP负载均衡技术是通过IPVS模块来实现的,IPVS是LVS集群系统的核心软件,它的主要作用是:安装在Director Server上,同时在Director Server上虚拟出一个IP地址,用户必须通过这个虚拟的IP地址访问服务。这个虚拟IP一般称为LVS的VIP,即Virtual IP。访问的请求首先经过VIP到达负载调度器,然后由负载调度器从Real Server列表中选取一个服务节点响应用户的请求。

 

当用户的请求到达负载调度器后,调度器如何将请求发送到提供服务的Real Server节点,而Real Server节点如何返回数据给用户,是IPVS实现的重点技术,

IPVS实现负载均衡机制有三种,分别是NAT、TUN和DR,详述如下:

? VS/NAT: 即(Virtual Server via Network Address Translation) 也就是网络地址翻译技术实现虚拟服务器,当用户请求到达调度器时,调度器将请求报文的目标地址(即虚拟IP地址)改写成选定的Real Server地址,同时报文的目标端口也改成选定的Real Server的相应端口,最后将报文请求发送到选定的Real Server。在服务器端得到数据后,Real Server返回数据给用户时,需要再次经过负载调度器将报文的源地址和源端口改成虚拟IP地址和相应端口,然后把数据发送给用户,完成整个负载调度过程。 可以看出,在NAT方式下,用户请求和响应报文都必须经过Director Server地址重写,当用户请求越来越多时,调度器的处理能力将称为瓶颈。

? VS/TUN :即(Virtual Server via IP Tunneling) 也就是IP隧道技术实现虚拟服务器。它的连接调度和管理与VS/NAT方式一样,只是它的报文转发方法不同,VS/TUN方式中,调度器采用IP隧道技术将用户请求转发到某个Real Server,而这个Real Server将直接响应用户的请求,不再经过前端调度器,此外,对Real Server的地域位置没有要求,可以和Director Server位于同一个网段,也可以是独立的一个网络。因此,在TUN方式中,调度器将只处理用户的报文请求,集群系统的吞吐量大大提高。

? VS/DR: 即(Virtual Server via Direct Routing) 也就是用直接路由技术实现虚拟服务器。它的连接调度和管理与VS/NAT和VS/TUN中的一样,但它的报文转发方法又有不同,VS/DR通过改写请求报文的MAC地址,将请求发送到Real Server,而Real Server将响应直接返回给客户,免去了VS/TUN中的IP隧道开销。这种方式是三种负载调度机制中性能最高最好的,但是必须要求Director Server与Real Server都有一块网卡连在同一物理网段上。

负载均衡调度算法

IPVS实现了如下八种负载调度算法:

? 轮叫调度:rr(Round Robin) “轮叫”调度也叫1:1调度,调度器通过“轮叫”调度算法将外部用户请求按顺序1:1的分配到集群中的每个Real Server上,这种算法平等地对待每一台Real Server,而不管服务器上实际的负载状况和连接状态.

? 加权轮叫调度:wrr (Weighted Round Robin) “加权轮叫”调度算法是根据Real Server的不同处理能力来调度访问请求。可以对每台Real Server设置不同的调度权值,对于性能相对较好的Real Server可以设置较高的权值,而对于处理能力较弱的Real Server,可以设置较低的权值,这样保证了处理能力强的服务器处理更多的访问流量。充分合理的利用了服务器资源。同时,调度器还可以自动查询Real Server的负载情况,并动态地调整其权值。

? 最少链接调度:lc(Least Connections) “最少连接”调度算法动态地将网络请求调度到已建立的链接数最少的服务器上。如果集群系统的真实服务器具有相近的系统性能,采用“最小连接”调度算法可以较好地均衡负载。 ? 加权最少链接调度:wlc(Weighted Least Connections) “加权最少链接调度”是“最少连接调度”的超集,每个服务节点可以用相应的权值表示其处理能力,而系统管理员可以动态的设置相应的权值,缺省权值为1,加权最小连接调度在分配新连接请求时尽可能使服务节点的已建立连接数和其权值成正比。

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

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

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

?源地址散列:sh(Source Hashing) "源地址散列"调度算法根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。

 

Ubuntu LVS DR模式实践部署

1、环境说明

系统版本:ubuntu14.04 LTS

LVS服务器:192.168.1.107

真实服务器:192.168.1.106,192.168.1.108

VIP:192.168.1.70

部署目的:用户请求192.168.1.70的报文转发至192.168.1.106和192.168.1.108上进行负载均衡。

2、安装LVS

由于LVS像iptables一样是工作在内核层,所以只需要安装模块ip_vs就可以了,并没有后台进程在跑

#aptitude install ipvsadm

# ipvsadm -v ipvsadm v1.26

# lsmod |grep ip_vs  #查看内核模块,有代表ipvsadm加载进内核当中,此时LVS安装完毕

ip_vs 136701 0

nf_conntrack 96976 1 ip_vs

libcrc32c 12644 3 xfs,btrfs,ip_vs

# ipvsadm -L -n #查看lvs规则

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

RemoteAddress:Port Forward Weight ActiveConn InActConn

# ipvsadm -L -c #查看连接情况

IPVS connection entries

pro expire state source virtual destination

3、配置LVS VIP服务

-A是添加一条虚拟服务器记录,即VIP。此处配置要选择算法。

#ipvsadm -A-t 192.168.1.70 -s wrr -p 300  #代理转发所有去往该IP TCP的报文,-s指定算法wrr为加权轮询算法,-p会话保持时间(默认值是300s)

#ipvsadm -A-t 192.168.1.70:8888 -s wrr -p 20   #代理转发去往该IP TCP8888端口的报文

VIP维护:

使用-E修改VIP设置

例:ipvsadm -E -t 192.168.1.70 -s rr -p 40   #可修改会话保持时间与算法。

使用-D删除VIP设置

例:ipvsadm -D -t 192.168.1.70   #删除该条VIP

 

4、配置LVS RIP规则

-a是添加VIP要对哪些真实服务器IP(即RIP)进行负载(默认是DR模式即-g)。

ipvsadm -a -t 192.168.1.70 -r 192.168.1.106 -g -w 1 #-r指定真实服务器IP,-g为选择DR模式(-m为NAT模式,-t为tunnel模式),-w选择权重。 ipvsadm -a -t 192.168.1.70 -r 192.168.1.108 -g -w 1

.........

#如果只对tcp 80端口进行负载,可使用如下命令

#ipvsadm -a-t 192.168.1.70:8888 -r 192.168.1.106:8888 -g -w 1

 

RIP维护:

使用-e修改RIP配置

例:ipvsadm -e -t 192.168.1.70 -r 192.168.1.106 -g -w 4 #修改这条RIP规则的权重。 使用-d删除RIP配置

例:ipvsadm -d -t 192.168.1.70 -r 192.168.1.106 -g -w 1 #删除该条RIP配置

或者使用脚本(LVS上执行)

vim /root/lvs.sh

#!/bin/bash

vip=192.168.1.70

rs1=192.168.1.106

rs2=192.168.1.108

#clear ipvs tables ipvsadm -C

#set LVS Server

ipvsadm -A -t $vip:8888 -s rr

ipvsadm -a -t $vip:8888 -r $rs1:8888 -g -w 1   #-w表示权重,默认为1

ipvsadm -a -t $vip:8888 -r $rs2:8888 -g   #不加-w 1效果同上句

# update /etc/sysctl.conf,以下配置重启后将复原

echo "1" >/proc/sys/net/ipv4/ip_forward   #启用ip转发

echo "1" >/proc/sys/net/ipv4/conf/all/send_redirects

echo "1" >/proc/sys/net/ipv4/conf/default/send_redirects

echo "1" >/proc/sys/net/ipv4/conf/eth0/send_redirects

#sysctl -p #查看sysctl的配置变化,可不执行

 

5、在真实服务器上配置VIP 在真实服务器(Real Server)上都配置上VIP,即192.168.1.70地址。

#ifconfig lo:0 192.168.1.70 netmask 255.255.255.255 broadcast 192.168.1.70 up

 

6、在真实服务器(Real Server)上关闭ARP响应

关闭真实服务器上loop口的arp回应,其它口的无须关闭。

默认arp_ignore和arp_announce的参数都是0,即回应所有目的IP是本机的arp请求。

 

在所有真实服务器上进行如下操作:

echo "1">/proc/sys/net/ipv4/conf/all/arp_ignore   #只回答目标IP地址是来访网络接口本地地址的ARP查询请求。

echo "2">/proc/sys/net/ipv4/conf/all/arp_announce   #对查询目标使用最适当的本地地址。

echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore

echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce

 

或用脚本vim /root/rs.sh(Real Server上执行)

#!/bin/bash

vip=192.168.1.70

ifconfig lo:0 $vip netmask 255.255.255.255 broadcast $vip up   #网关要和虚ip一样,掩码不能同于eth0的

route add -host $vip dev lo:0   #添加永久路由

#echo "0" >/proc/sys/net/ipv4/ip_forward #关闭real server ip转发,2.6.*内核默认是关闭的

echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore

echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce

echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore

echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

#sysctl -p   #查看sysctl的配置变化,可不执行

 

7、开启内核转发功能(如果已经执行lvs.sh这步可以省略)

在lvs上开启内核转发功能。

#echo ‘net.ipv4.ip_forward=1‘ >>/etc/sysctl.conf

#sysctl -p

 

8、LVS测试

由于真实服务器上已搭建http服务,刚好设置的lvs是转发所有tcp连接,

可以直接访问192.168.1.70。

http://192.168.1.70:8888

LVS上执行

#ipvsadm -L -c #查看lvs转发记录,确定请求转发成功。

pro expire state source virtual destination

TCP 00:05 NONE 192.168.1.98:0 192.168.1.70:8888 192.168.1.108:8888

TCP 01:20 FIN_WAIT 192.168.1.98:55936 192.168.1.70:8888 192.168.1.108:8888

 

至此lvs搭建成功。

9、lvs补充思考

1、 自身无法对真实服务器保活,如果出现服务器down情况,还会向down的服务器转发请求。 解决方法是keepalived或自已写脚本来监测连通性再清除相应规则。 2、一台LVS服务器会出现单点故障,需要有备份LVS服务器 解决方法是keepalived来进行LVS故障接管。

Ipvsadm 命令参数详解

-A (--add-service) 在内核的虚拟服务器列表中添加一条新的虚拟IP记录。也就是增加一台新的虚拟服务器。虚拟IP也就是虚拟服务器的IP地址。

-E (--edit-service) 编辑内核虚拟服务器列表中的一条虚拟服务器记录

-D (--delete-service) 删除内核虚拟服务器列表中的一条虚拟服务器记录

-C (--clear) 清除内核虚拟服务器列表中的所有记录

-R (--restore) 恢复虚拟服务器规则

-S (--save) 保存虚拟服务器规则,输出为-R 选项可读的格式

-a (--add-server) 在内核虚拟服务器列表的一条记录里添加一条新的Real Server记录。也就是在一个虚拟服务器中增加一台新的Real Server

-e (--edit-server) 编辑一条虚拟服务器记录中的某条Real Server记录

-d (--delete-server) 删除一条虚拟服务器记录中的某条Real Server记录

-L|-l –list 显示内核中虚拟服务器列表

-Z (--zero) 虚拟服务器列表计数器清零(清空当前的连接数量等) -

-set tcp tcpfin udp 设置连接超时值

-t 说明虚拟服务器提供的是tcp服务,此选项后面跟如下格式: [virtual-service-address:port] or [real-server-ip:port]

-u 说明虚拟服务器提供的是udp服务,此选项后面跟如下格式: [virtual-service-address:port] or [real-server-ip:port]

-f fwmark 说明是经过iptables标记过的服务类型

-s 此选项后面跟LVS使用的调度算法 有这样几个选项: rr|wrr|lc|wlc|lblc|lblcr|dh|sh 默认的调度算法是: wlc

-p [timeout] 在某个Real Server上持续的服务时间。也就是说来自同一个用户的多次请求,将被同一个Real Server处理。此参数一般用于有动态请求的操作中,timeout 的默认值为300 秒。例如:-p 600,表示持续服务时间为600秒。

-r 指定Real Server的IP地址,此选项后面跟如下格式: [real-server-ip:port]

-g (--gatewaying) 指定LVS 的工作模式为直接路由模式(此模式是LVS 默认工作模式)

-i (-ipip) 指定LVS 的工作模式为隧道模式

-m (--masquerading) 指定LVS 的工作模式为NAT模式

-w (--weight) weight 指定Real Server的权值

-c (--connection) 显示LVS目前的连接信息 如:ipvsadm -L -c

-L --timeout 显示“tcp tcpfin udp”的timeout值,如:ipvsadm-L --timeout

-L --daemon 显示同步守护进程状态,例如:ipvsadm -L –daemon

-L --stats 显示统计信息,例如:ipvsadm -L –stats

-L --rate 显示速率信息,例如:ipvsadm -L --rate

-L --sort 对虚拟服务器和真实服务器排序输出,例如:ipvsadm -L –sort

Linux负载均衡概念与实践(一)

标签:

原文地址:http://www.cnblogs.com/mhten/p/4936445.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!