Cluster了解+LB{ LVS(四种模式)+ipvs+lvs持久连接 }
Posted jerryzao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cluster了解+LB{ LVS(四种模式)+ipvs+lvs持久连接 }相关的知识,希望对你有一定的参考价值。
Cluster: 系统扩展的两种思路: scale up:向上扩展 -- 性能更好的主机,替换旧的主机 scale out:横向扩展 -- 添加服务器(但是服务是可以分开的,独立的) cookie:服务器端生成一个cookie-id,发送给客户端,客户端每次访问,都会将cookie发送给服务器端 session:服务器端会比对cookie和seesion的对应情况(服务器内存中) 实现 LB(负载均衡)-- 问题所在 1、DNS: 不要使用dns 去实现 LB,因为DNS 解析会缓存,所以效果很差 2、前端实现一个调度器: 如果请求和响应都通过 调度器,导致压力很大。 集群类型: LB:负载均衡,均衡负载,调度到不同的服务器访问资源(同一或不同资源) HA:高可用,提高冗余,服务器一直在线,一个down掉,其他服务器取而代之 HP:集中式的高性能服务器 不同于 分布式 平均无故障时间/(平均无故障时间 + 平均修复时间) -- 90% 95% 99% 99.9% 99.99% 系统: 可扩展性 可用性: 服务器是否随时可用 容量: 系统运维:可用 ---> 标准化 --- > 自动化 ****构建高可扩展性系统的重要原则:在系统内部尽量避免串行和交互 GLSB:Global Service Load Blancing SLB:Service Load Blancing 静态内容的响应远大于动态响应,动态服务器是无法缓存的,基于CDN的都是静态服务器 缓存是KEY-value存储,所以查询缓存要快很多。但是如果数据过期了,查缓存时间就多了。 构建一个系统: 1、分层:每个功能一个层,每个服务器制作自己的事 2、分割:不同应用分割道不同服务器 3、分布式:无法分割的 分布式应用 分布式静态资源 分布式数据和存储 分布式计算 通过量: 容纳量: 吞吐量:最大吞吐量 保证可接受容量的条件下,平均吞吐量。 LB 集群的实现: 后台服务器具有全部的数据集 硬件实现: F5 BIG-IP Citrix NetScaler A10 软件: LVS Haproxy nginx ats(apache traffic server) httpd(proxy模块) varnish perlbal 基于工作的协议层次划分: 传输层: LVS, haproxy(mode可以模拟tcp) 应用层:(反向代理) nginx -- 应用程序 haproxy -- 应用程序 ats perlbal 注意: LVS 依附于netfilter工作于内核,只需要 端口 对于应用程序,本身就需要一个套接字,而端口最多65535个,所以并发数最多65535个 监听套接字 已连接套接字 网站并发连接数2-3w,pv量就达到千万级别了 所以一般不会用到lvs 这种百万级别的并发量的并发,而且一般这个级别的时候,可能用CDN了,不会直接到达服务器了。 LVS:工作在传输层的LB均衡器 工作于netfilter上的 LVS:Linux Virtual Server虚拟服务器,不是真正提供服务的 LVS也称为---L4:4层路由, 根据请求报文的目标IP 和PORT 将其转发后端主机集群中的某一台(根据挑选算法) netfilter: PREROUTING ---> INPUT PREROUTING ---> FORWARD ---> POSTROUTING OUTPUT ---> POSTROUTING DNAT: PREROUTING上 在路由转发之前,发现ip不是本机,就不会转发了 LVS: 工作在INPUT 上,发现是集群服务(例如:某个端口作为集群服务),就强行改变,到POSTROUTING PREROUTING ---> INPUT --> POSTROUTING 在内核中工作 就不是服务 LVS: 用户空间:ipvsadm命令行工具,用于管理集群服务, 增删查改 内核空间:ipvs工作于内核中INPUT连上 内核编译时加载的模块: /boot/config-2.6.32-696.el6.x86_64 y:已经加载 m:可以手动在加载 支持的协议: TCP,UDP ,EST,AH_EXT,SCTP等 lvs arch: 调度器:director,dispatcher,balancer 后端:real server CIP VIP DIP RIP lvs 类型: lvs-nat lvs-dr(diretct routing) lvs-tun(隧道) lvs-fullnat lvs-nat: DIP,RIP:内网地址 VIP:外网 请求: CIP-VIP CIP-DIP CIP-RIP PREROUTING --> INPUT --> POSTROUTING 响应: RIP-CIP VIP-CIP PREROUTING --> FORWARD --> POSTROUTING 维持 NAT 会话表 多目标的DNAT(iptables):通过修改请求报文的目标IP地址(同时可能会修改目标端口)至挑选出的某RS 的RIP地址,实现转发。 1、RS应该和DIP 应该使用私有网址,RS的网关指向DIP 2、请求和响应的报文 都要经由director转发,极高负载场景中,direxctor会成为瓶颈 3、支持端口映射 4、RS 可以使用 windows,Linux等任意OS 5、RIP 和 DIP 必须在同一IP 网络(加个路由,没必要) lvs-dr:直接转发 通过修改请求报文的目标MAC地址进行转发的。 在网路上传输,经过路由和网关,sip dip是不会变的,但是mac是会变的。直到LAN D:DIP,VIP R:RIP,VIP D 通过arp广播,获取的是RS的mac地址,到达D,发现mac变为RS,在转发到RS 1、保证前端路由器将目标IP 为VIP的请求报文发送给director 解决方案: 路由器跟D 绑定(但是D挂了,还得重新绑定) 修改RS 内核参数 2、RS的RIP 可以使用私有地址,可以使用公网地址 3、RS 和 D 必须在同一物理网络中 4、请求报文 通过 D 调用,响应报文一定不能经过D 5、不支持端口映射:请求80,RS回应8080,就错了被 6、RS可以大多数os 7、RS的网关不能指向DIP lvs-tun: 不修改请求报文的ip 首部,而是通过在原有的ip首部外面再封装一个ip首部 响应:rs直接响应客户端 cip ---> vip 再封装一个ip首部(dip ---> rip) 1、RIP DIP VIP全部是公网 2、RS的网关 不能指向DIP 3、请求报文必须经由D 调度,响应报文不能D调度 4、不支持端口映射 5、RS的os 必须支持隧道功能 lvs-fullnat: ups:备用电源 D:同时修改原地址和目标地址 1、VIP是公网地址, rip和dip 是私网地址,二者无须同一网络中 2、RS 接收到的请求报文的原地址为DIP,因此要响应给DIP 3、请求报文和响应报文都必须经由 D 4、支持端口映射 5、RS的os可以使用任意OS http:stateless无状态 session保持机制: session绑定: 将来自于同一用户的请求始终定向至同一个服务,维持一个会话表:追踪同一个用户 ip_hash:原地址hash,太粗糙,基于snet-ip访问,就不行了 cookie绑定:session绑定上实现,LVS无法实现 但是某服务器宕机后,session就没了 session集群 同步session信息 但是网络中充斥大量的session,浪费带宽。 session服务器 集中管理。session持久化的话,即便关机,也是没关系的 --- redis 调度算法: cat /boot/config-2.6.32-696.el6.x86_64 静态方法:仅根据算法本身进行调度,起点公平 RR:round robin轮询 WRR:weight rr 权重 SH:source hash 原地址hsah, 实现session保持 -- 损坏负载均衡效果,来自同一IP的请求始终调度到同一服务器 DH:destation hash,类似:访问同一个资源,会定向到同一个服务器(lvs无法实现url调度,只能ip和port,只是举例说明) 同一个防火墙出去的,通过同一个防火墙进来。 动态方法:根据算法及各RS的当前负载状态进行调度,结果公平 Overhead(当前负载)= LC:least connection,哪个服务器链接数最少,就调度到哪个 刚开始或者Overhead一样:自上而下挑选 Overhead= active * 256 + inactive WLC:weight LC overhead = (active * 256 + inactive) / weight 缺陷: 如果计算后都一样的值,这是从上往下选,但是正好,第一个负载很重 SED:最短期望延迟 初始连接高权重优先 (active+1)* 256 /weight 缺陷: 如果两台:weight=4,1 则来的都是在4 上 NQ:never queue sed的改进 第一轮均匀分配,后续SED LBLC:locality-Base LC :动态的DH 算法 大量缓存的时候,才会用 正向代理情形下的cache server 调度 LBLCR:带复制的LBLC 解决LBLC负载不均衡,从负载重的复制到负载轻的 ipvs:的集群服务 1、一个ipvs主机可同时定义多个cluster service 2、一个cluster service 上至少有一个real server 定义时:指明lvs-type,以及lvs 调度算法 ipvsadm用法: 1、管理集群服务 ipvsadm -A|E -t|u|f service-address [-s scheduler] ipvsadm -D -t|u|f service-address service-address: tcp: -t ip:port udp: -u ip:port fwm: -f mark 防火墙标记,表示从这通过的 -s: 默认wlc 2、管理集群服务中的RS ipvsadm -a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight] [-x upper] [-y lower] ipvsadm -d -t|u|f service-address -r server-address server-address: ip[:port] -g:dr 模型。默认 -i:ipip tun模型 -m:nat 查看和清理: ipvsadm -C ipvsadm -L|l [options] -n:基于数字格式显示地址和端口 -c:显示ipvs连接 --stats: 入站 包个数,入站字节数 --rate:速率 pps:每妙包个数 Bps:字节数 --exact:显示精确值 保存和重载: ipvsadm -R ipvsadm -S [-n] 置零计数器 ipvsadm -Z [-t|u|f service-address] 测试: nat: A --- > director eth0: vip eth1: dip web1 ---> eth0 rip1 web2 ---> eth0 rip2 1、iptables 关闭***或者清空**** 2、/etc/sysctl.conf 开启转发 3、规则: ipvsadm -A -t vip:80 -s rr ipvsadm -L -n ---查看 ipvsadm -a -t vip:80 -r rip1 -m ipvsadm -a -t vip:80 -r rip2 -m ipvsadm -L -n ---查看 ipvsadm -S > /etc/sysconfig/ipvsadm 保存 ipvsadm -C 清空 ipvsadm -L -n ---查看 ipvsadm -R 重载 修改: 修改算法: ipvsadm -E -t vip:80 -s sh 端口映射 ipvsadm -e -t vip:80 -r rip1:8080 -m 删除: ipvsadm -d -t vip:80 -r rip1:8080 删除集群: -D **web是https的话,每个服务器用同一个证书和私钥 因为lvs是内核中工作,不会代替c和s 之间建立ssl会话 又因为访问的是同一个域名,所以,需要同一个证书和秘钥 短连接 和 长连接的问题** 有些特殊协议是不能lvs调度的 例如ftp:被动模式的ftp端口问题 dr: director: eht0 ---> dip eth0:0 ---> vip/32 web1: eth0 rip1 lo:0 vip web2: eth0 rip2 lo:0 vip arp广播: annouce:是否通告别人 0:把自己所有的地址都告诉别人 1:尽量避免不要同不是同一网络的 告诉别人 2:只能通过网卡出去 ignore:响不响应 0:有,就通知 1:从哪个接口进来,只有配置到该进来的接口 才响应 内核参数: # echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore # echo 2 > /proc/sys/net/ipv4/conf/all/arp_annouce # echo 1 > /proc/sys/net/ipv4/conf/INTERFACE/arp_ignore # echo 2 > /proc/sys/net/ipv4/conf/INTERFACE/arp_annouce 注意:INTERFACE为你的物理接口; # ifconfig lo:0 $vip netmask 255.255.255.255 broadcast $vip up # route add -host $vip dev lo:0 桥接: 目前的以太网都是通过交换机通信的 物理机的物理网卡,模拟成物理交换设备,虚拟机交换机与之相连 在同一网段中就可以通信 NAT:物理机上虚拟一个网卡 与 虚拟交换机建立关系,虚拟机网关指向虚拟网卡 经过物理网卡时,地址转换为网卡的地址 HOST-Only:没有nat 虚拟通道: vmnet2.... 不跟物理机通信 防火墙标记: -f 选项 fwm:用户请求到达时,在 PREROUTING 设置标记 -j MARK --set-mark 10 ipvs: -A -f 10 将两种不同的服务一起调度: 一台服务器有如下服务: 一个443 一个80 打上同一个标记 如 10 ipvs规则直接用10 即可,否则每个都得定义成各自服务的集群 示例: ~]# iptables -t mangle -A PREROUTING -d 172.16.100.9 -p tcp --dport 80 -j MARK --set-mark 99 ~]# iptables -t mangle -A PREROUTING -d 172.16.100.9 -p tcp --dport 443 -j MARK --set-mark 99 ~]# ipvsadm -A -f 99 -s rr -p ~]# ipvsadm -a -f 99 -r 172.16.100.68 -g ~]# ipvsadm -a -f 99 -r 172.16.100.69 -g lvs 持久连接: session保持: 绑定: 复制: 服务器: session绑定: 对多个共享同一组RS的服务,统一进行帮定(sh 算法无法解决) lvs persistence:lvs的持久连接 功能:无论ipvs使用何种调度方法,其都能事项将来自于同一个client的请求始终定向至第一次调度时挑选出的RS 持久连接模板:独立于算法外:(第一次请求时,或者倒计时变为0了,使用定义的算法调度) sourceip -- RS -- timer -p选项,默认300秒 示例: ~]# iptables -t mangle -A PREROUTING -d 172.16.100.9 -p tcp --dport 80 -j MARK --set-mark 99 ~]# iptables -t mangle -A PREROUTING -d 172.16.100.9 -p tcp --dport 443 -j MARK --set-mark 99 ~]# ipvsadm -A -f 99 -s rr -p ~]# ipvsadm -a -f 99 -r 172.16.100.68 -g ~]# ipvsadm -a -f 99 -r 172.16.100.69 -g 持久连接的实现: 每端口持久:PPC,单服务持久调度,sh算法实现的功能 每fwm持久:PFWMC,单FWM持久调度 每客户端持久:PCC,单客户端持久调度, director会将用户的任何请求都识别为集群服务,并向RS调度,而且绑定到同一个RS上 1-65535 端口0:表示所有服务 ipvsadm -A -t 172.16.100.68:0 -s rr HA: SPOF:单点故障 lvs HA功能: director:在节点级别进行冗余;HA集群解决方案:keepalived,; real server:让director 健康状态检测,并能够完成自动上下线; 健康时:online 非健康时:offline 如何对real server做健康状态检测: (1) ip层:探测主机的存活状态 ping;----单服务 并不一定 正常,如 web服务器,虽然主机好了,但是web就好吗? (2) 传输层:探测端口的可用性;----端口好,不一定网页就能访问 (3) 应用层:请求关键的某资源;----直接请求某资源 状态变化: ok --> failure --> failure --> failure rs: down soft state --> hard state failure --> ok rs: up backup(sorry_server): 示例脚本: #!/bin/bash # fwm=6 sorry_server=127.0.0.1 rs=(‘172.16.100.21‘ ‘172.16.100.22‘) rw=(‘1‘ ‘2‘) type=‘-g‘ chkloop=3 rsstatus=(0 0) logfile=/var/log/ipvs_health_check.log addrs() { ipvsadm -a -f $fwm -r $1 $type -w $2 [ $? -eq 0 ] && return 0 || return 1 } delrs() { ipvsadm -d -f $fwm -r $1 [ $? -eq 0 ] && return 0 || return 1 } chkrs() { local i=1 while [ $i -le $chkloop ]; do if curl --connect-timeout 1 -s http://$1/.health.html | grep "OK" &> /dev/null; then return 0 fi let i++ sleep 1 done return 1 } initstatus() { for host in `seq 0 $[${#rs[@]}-1]`; do if chkrs ${rs[$host]}; then if [ ${rsstatus[$host]} -eq 0 ]; then rsstatus[$host]=1 fi else if [ ${rsstatus[$host]} -eq 1 ]; then rsstatus[$host]=0 fi fi done } initstatus while :; do for host in `seq 0 $[${#rs[@]}-1]`; do if chkrs ${rs[$host]}; then if [ ${rsstatus[$host]} -eq 0 ]; then addrs ${rs[$host]} ${rw[$host]} [ $? -eq 0 ] && rsstatus[$host]=1 fi else if [ ${rsstatus[$host]} -eq 1 ]; then delrs ${rs[$host]} ${rw[$host]} [ $? -eq 0 ] && rsstatus[$host]=0 fi fi done sleep 5 done 附:director和rs的示例脚本 DR类型director脚本示例: #!/bin/bash # vip=172.16.100.33 rip=(‘172.16.100.8‘ ‘172.16.100.9‘) weight=(‘1‘ ‘2‘) port=80 scheduler=rr ipvstype=‘-g‘ case $1 in start) iptables -F -t filter ipvsadm -C ifconfig eth0:0 $vip broadcast $vip netmask 255.255.255.255 up echo 1 > /proc/sys/net/ipv4/ip_forward ipvsadm -A -t $vip:$port -s $scheduler [ $? -eq 0 ] && echo "ipvs service $vip:$port added." || exit 2 for i in `seq 0 $[${#rip[@]}-1]`; do ipvsadm -a -t $vip:$port -r ${rip[$i]} $ipvstype -w ${weight[$i]} [ $? -eq 0 ] && echo "RS ${rip[$i]} added." done touch /var/lock/subsys/ipvs ;; stop) echo 0 > /proc/sys/net/ipv4/ip_forward ipvsadm -C ifconfig eth0:0 down rm -f /var/lock/subsys/ipvs echo "ipvs stopped." ;; status) if [ -f /var/lock/subsys/ipvs ]; then echo "ipvs is running." ipvsadm -L -n else echo "ipvs is stopped." fi ;; *) echo "Usage: `basename $0` {start|stop|status}" exit 3 ;; esac DR类型RS脚本示例: #!/bin/bash # vip=172.16.100.33 interface="lo:0" case $1 in start) echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce ifconfig $interface $vip broadcast $vip netmask 255.255.255.255 up route add -host $vip dev $interface ;; stop) echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce ifconfig $interface down ;; status) if ifconfig lo:0 |grep $vip &> /dev/null; then echo "ipvs is running." else echo "ipvs is stopped." fi ;; *) echo "Usage: `basename $0` {start|stop|status}" exit 1 esac
以上是关于Cluster了解+LB{ LVS(四种模式)+ipvs+lvs持久连接 }的主要内容,如果未能解决你的问题,请参考以下文章