LVS负载均衡内功心法+外功招式

Stella981
• 阅读 392

LVS是Linux Virtual Server的缩写,即Linux虚拟服务器,是由章文嵩博士主导开发的开源负载均衡项目,目前LVS已经被集成到Linuxd内核模块中。章文嵩博士曾任淘宝网技术总监、阿里副总裁、阿里云CTO,2016年任滴滴出行高级副总裁。章博士曾经总结道:做技术不仅要有一份执着和细致的心,还要有一份平静的心态。就拿开源项目来讲,都是免费的,没有收入,收获的是自己的满足感,而非金钱,这时候更需要冷静和平和的心态。把这句话送给我自己,也送给大家。(貌似有点扯远了)

时代背景

21世纪人类进入以网络为中心的信息时代,人们对互联网的使用呈指数级增长,单机模式已经无法满足业务服务高性能、高可用、可伸缩的需求了。

通过高性能网络或局域网互联的服务器集群正成为实现高性能、高可用、可伸缩的有效架构。LVS项目给出了基于IP的数据请求负载均衡调度方案。在LVS集群中,服务器集群对客户端来说是透明的,客户端访问负载均衡服务器,请求会发给LVS调度器,调度器根据设定的算法决定将请求发送给后端某台真实的服务器。后端多台服务器共同实现了集群的高性能,可伸缩性是通过在集群中透明的加入和剔除一个节点来达到,通过监测后端节点、重置系统达到集群的高可用性。

LVS集群的体系结构

LVS负载均衡内功心法+外功招式

LVS集群架构主要由三部分组成:

1.负载调度器:负责客户请求的分发,根据预设的算法选中后端一台真实的服务器上,然后将请求发送到这台真实服务器上。它可以是基于IP负载均衡技术的负载调度器,也可以是基于内容请求分发的负载调度器,或者是两者的结合。

2.服务器池:是一组真正执行客户请求的服务器。

3.后端存储:为服务器池提供一个共享的存储区,这样很容易使得服务器池拥有相同的内容,提供相同的服务。如果不采用共享存储的方式,这就要求每个后端服务器上都要有相同的内容。

LVS术语

**1.VS:Virtual Server,虚拟服务器。

2.DS:Director Server,指负载均衡节点。

3.RS:Real Server,后端真实的服务器。

4.VIP:Virtual IP,用户请求的目标IP地址,指LVS上的虚拟IP。

5.RIP:Real Server IP,后端服务器的IP地址。

6.CIP:Client IP,客户端的IP地址。

**

基于IP的负载均衡技术

VS/NAT


NAT(Network Address Translation)即网络地址转换,其原理是通过对数据报文头(目标地址、源地址和端口等)的修改,使位于企业内部的私有IP可以访问外网,以及外部用户可以访问位于公司内部的私有IP。,该模式下LVS调度器一般配置两块网卡设置不同的IP。当客户通过VIP(Virtual IP Address)访问网络服务时,调度器会根据连接调度算法从后台真实服务器中选出一台,将报文的目标地址VIP改写成选中的服务器的IP地址,报文的目标端口改写成选中的服务器的对应端口,最后将修改后的报文发给选中的服务器。同时,调度器会在连接Hash表记录这个连接,当这个连接的下一个报文到达时,从连接 Hash 表中可以得到原选定服务器的地址和端口,进行同样的改写操作,并将报文传给原选定的服务器。当来自真实服务器的响应报文经过调度器时,调度器将报文的源地址和源端口改为VIP和相应的端口,再把报文发给用户。这样,客户所看到的只是在VIP上提供的服务,而服务器集群的结构对用户是透明的。

举个例子:

LVS负载均衡内功心法+外功招式

1.第一步用户通过对外提供的VIP(126.124.1.1:80)访问服务器。这时候请求报文中含有以下源地址、目标地址和端口。

source

202.103.2.1:40124

dest

126.124.1.1:80

2.LVS收到请求后,会根据预设定的算法从后端选出一台真实的服务器。在转发报文之前会把报文中的目标IP和端口修改为被选中的后端真实服务器的IP和端口(假设192.168.94.2被选中),然后将数据包转发给真实服务器。

修改后:

source

202.103.2.1:40124

dest

192.168.94.2:8080

3.后端真实服务器处理完之后将响应报文返回给LVS,此时报文的源地址端口是后端真实服务的IP端口,调度器得到响应报文后会将源地址修改为VIP和调度器对应端口。

修改前:

source

192.168.94.2:8080

dest

202.103.2.1:40124

修改后:

source

126.124.1.1:80

dest

202.103.2.1:40124

这样,客户就认为是从126.124.1.1:80得到的响应,而不知道后端真实服务器的存在。

VS/TUN

LVS负载均衡内功心法+外功招式

在VS/NAT模式下,请求和响应都要通过负载调度器,当真实服务器数量较多时,调度器就会成为整个集群的瓶颈。我们知道,一般情况下请求报文一般要远小于响应报文,所以如果能将请求和响应分开处理,比如LVS只负责请求而响应直接返回给客户,这样就能极大的提高集群的处理效率。

IP隧道(IP tunneling)是将一个IP报文封装在另一个IP报文的技术,这可以使得目标为一个IP地址的数据报文能被封装和转发到另一个IP地址,从而实现将一个目标地址为调度器VIP的数据包封装,通过隧道转发给后端某台真实服务器。后端真实服务器收到报文后,先将报文解封获得原来目标地址为VIP的报文,服务器发现VIP地址被配置在本地的IP隧道设备上,所以就处理这个请求,然后根据路由表将响应报文直接返回给客户。在这里,请求报文的目标地址为VIP,响应报文的源地址也为VIP,所以响应报文不需要作任何修改,可以直接返回给客户而不需要再经过调度器,客户不会知道是哪一台服务器处理的。

VS/DR

LVS负载均衡内功心法+外功招式

DR模式也叫直接路由模式,该模式下LVS依然承担数据入站请求以及根据预设的算法选出合理的真实服务器,最终由后端真实服务器直接将响应包发送给客户。与TUN模式不同的事,直接路由模式要求调度器和后端真实服务器必须在同一个局域网内,VIP地址需要在调度器和后端所有服务器间共享。

在VS/DR模式下,调度器根据各个服务器的负载情况,动态地选择一台服务器,不修改也不封装IP报文,而是将数据帧的MAC地址改为选出服务器的MAC地址,再将修改后的数据帧在与服务器组的局域网上发送。因为数据帧的MAC地址是选出的服务器,所以服务器肯定可以收到这个数据帧,从中可以获得该请求报文。在 VS/DR 中,请求报文的目标地址为VIP,响应报文的源地址也为 VIP,所以响应报文不需要作任何修改,可以直接返回给客户,客户认为得到正常的服务,而不会知道是哪一台服务器处理的。

LVS调度算法

1.轮询调度(RR)

轮叫调度(Round Robin Scheduling)算法就是以轮叫的方式依次将请求调度不同的服务器。轮叫调度算法假设所有服务器处理性能均相同,调度器会将请求平均分到后端真实服务器上。

2.加权轮询调度(WRR)

加权轮询调度(Weighted Round-Robin Scheduling)比RR算法多了一个加权的概念,可以给RS设置权重,权重越高,分发的请求越多。比如服务器A的权重是1,服务器B的权重是2,则服务器B收到的分发请求一般是A的2倍。

3.目标地址散列调度(DH)

目标地址散列调度(Destination Hashing Scheduling)是针对目标IP地址的负载均衡,它会以目标地址为关键字查找一个静态hash表来获得需要的RS。

4.源地址散列调度(SH)

该算法正好与目标地址散列调度算法相反,它根据请求的源 IP 地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器。一般情况下,在一定时间内,同一个IP的请求会发往后端同一台服务器。

5.最小连接调度(LC)

最小连接调度是一种动态调度算法,它通过服务器当前所活跃的连接数来估计服务器的负载情况。比如RS1的连接数比RS2少,那么调度器就会优先把下一个请求发给RS1。

6.加权最小连接调度(WLC)

这个比LC算法多了一个加权的概念,当连接数相近时,权重越大,越优先被分配请求。

7.基于局部性的最少链接(LBLC)

LBLC调度算法先根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于其一半的工作负载,则用“最少链接”的原则选出一个可用的服务器,将请求发送到该服务器。

8.带复制的基于局部性最少链接(LBLCR)

该算法也是针对目标 IP 地址的负载均衡,目前主要用于Cache集群系统,不太常用。

LVS常用命令

1.ipvsadm 参数

-A添加一个虚拟服务,使用IP地址、端口号、协议来定义一个虚拟服务。

-E编辑一个虚拟服务

-D删除一个虚拟服务

-C情况虚拟服务

-R从标准输入还原虚拟服务

-S保存虚拟服务规则至标准输出,输出的规则可以用-R还原

-a在虚拟服务中增加一个real server

-e在虚拟服务中编辑一台real server

-d在虚拟服务中删除一台real server

-L显示虚拟服务列表

-t使用TCP协议,该参数后需要跟主机和端口信息

-u使用UDP协议,该参数后需要跟主机和端口信息

-s指定lvs需要使用的调度算法

-r设置真实服务器的IP地址和端口

-g设置LVS工作模式为DR模式

-i设置LVS工作模式为TUN模式

-m设置LVS工作模式为NAT模式

-w设置指定服务器的权重

-c显示连接状态,一般配合-L使用

-n数字格式输出,IP和端口信息会以数字格式输出

2.添加一个虚拟服务,设置调度算法为轮询算法,将发送到207.175.44.110:80端口的传入请求分配给后端3台真实的服务器的80端口上,本例中采用NAT模式。

ipvsadm -A -t 207.175.44.110:80 -s rr

3.删除后端一台真实服务器192.168.10.1:80

ipvsadm –d –t 207.175.44.110:80 –r 192.168.10.1:80

4.编辑虚拟服务器的调度算法为加权轮询

ipvsadm –E –t 207.175.44.110:80 –s wrr

5.虚拟服务规则表的备份和还原

ipvsadm –Sn >/tmp/ipvs.bak #备份

6.查看IPVS调度状态

ipvsadm –Lnc

7.查看LVS规则

ipvsadm -Ln

LVS的黄金搭档-keepalived

keepalived顾名思义,保持存活,它是为Linux系统提供简单高效的负载均衡及高可用的解决方案。它通过VRRP(Virtual Router Redundancy Protocol)协议实现高可用架构。VRRP协议是为了在静态路由环境下防止单点故障而设计的主从灾备协议,它可以实现在一个集群环境中,当主机发生故障时,能将业务自动切换到备机。VRRP将多台设备虚拟成一个设备集群,对外只提供一个虚拟的IP,正常情况下,只有一个设备可以拥有这个IP,主设备会不断发送自己的状态给备机,当备机发现主机不可达时,会根据优先级选举出新的主机。

Keepalived主要配置文件是/etc/keepalived/keepalived.conf,配置文件主要分为全局配置、VRRP配置块、LVS配置块,具体核心参数解释如下:

LVS负载均衡内功心法+外功招式

实战操作

1.环境准备(redhat 6.9)

  1. 关闭selinux:

    vi /etc/selinux/config

  2. 关闭防火墙(NAT负载模式需要根据业务需求配置iptables,DR模式需要直接关掉)

    chkconfig --level 2345 iptables off

2.配置本地yum源(如果已有yum源,该步骤请忽略)

  1. 挂载光盘

    mkdir /mnt/media

  2. 新建本地yum源的配置文件

    vi /etc/yum.repos.d/local.repo

3)清理yum

yum clean all

3.安装部署ipvs管理工具ipvsadm

  1. 确保Linux的kernel支持ipvs算法,检查内核是否支持

    modprobe -l|grep ipvs

  2. 使用rpm包安装

    yum install ipvsadm*

  3. 激活IPVS内核模块

    modprobes ip_vs

  4. 检查ipvsadm是否完整安装( modprob ip_vs装载)

    lsmod|grep ip_vs

4.高可用介质keepalived安装(采用编译安装的方式,也可直接安装rpm包)

  1. 安装编译工具

    yum install make -y

  2. 安装编译环境

    yum install gcc* -y

  3. 安装依赖程序

    yum install kernel-devel -y

  4. 可以用此命令建立内核链接

    ln -s /usr/src/kernels/$(uname -r)/ /usr/src/linux

5.安装keepalived软件

  1. 解压程序包

    tar -zxvf keepalived1.2.2.tar.gz

  2. 配置编译环境

    cd keepalived-1.2.2

注意上面的kernel的链接,如果没有做链接,很可能导致

Use IPVS Framework       : Yes(必须是yes)

IPVS sync daemon support : Yes(必须是yes)

这两个地方是NO

  1. 编译安装

    make && make install

6.配置HA为系统服务,并设置开机启动

cp /usr/local/etc/rc.d/init.d/keepalived /etc/init.d/

7.修改keepalived配置文件,具体配置需要根据业务场景定制,示例可参考上一章节《LVS

的黄金搭档-keepalived》中的配图,本例采用DR模式。

修改完配置文件后启动keepalived,启停命令如下:

停止:service keepalived stop

8.在LVS(DR)模式下,所有的真实服务器都配置了VIP地址,因此需要设置服务器不进行针对VIP地址的ARP广播,linux中可以直接通过arp_ignore和arp_announce两个参数来实现。

arp_ignore:

0:代表任何网络接口接到ARP请求后,如果本机的任意接口有该IP,则予以响应。

1:某个网络接口收到ARP请求后,判断请求的IP是否在本接口,是则回应,否则不回应。LVS调度器会把客户请求发给真实服务器的某个本机接口(比如eth0)而真实服务器的VIP地址会配置在回环网卡上。

arp_announce:

0:任何网络接口接收到ARP请求后,如果本机上任何接口有该IP,则给予响应。

1:尽量避免响应MAC地址非本网络接口IP地址的ARP请求。

2:不响应MAC地址非本网络接口IP地址的ARP请求。

具体脚本如下:

#!/bin/bash

9.注意事项

现在大多数网卡都具有lro和gro功能,即网卡收包时将同一流的小包合并成大包(tcpdump抓包时可以看到>MTU 1500 bytes的数据包)交给内核协议栈,lvs内核模块在处理>MTU(Maximum Transmission Unit,网络上传输的最大数据包,ifconfig可以查看)的数据包时,会丢弃,如果lvs传输大文件时,容易出现丢包、传输速度慢的现象。

建议关掉lro和gro。

查看网卡属性

ethtool -k eth0

关闭网卡gro和lro功能

/usr/sbin/ethtool -K eth0 gro off

LVS负载均衡内功心法+外功招式

为了方便大家交流,我建了一个微信群,大家可以在群里聊技术、聊理想、聊生活,欢迎加入!

LVS负载均衡内功心法+外功招式

往期推荐

[

GTID,你了解多少?

](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzIzNDg0MjMzNQ%3D%3D%26mid%3D2247485630%26idx%3D1%26sn%3Da8d6f64f45872b9a163a7eacc411d24a%26chksm%3De8f1790edf86f01835a57f2a166cf9ac913f3d25e0df8d2221c6ccc4709f0901afd1c37be310%26scene%3D21%23wechat_redirect)

[

Redis的数据安全

](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzIzNDg0MjMzNQ%3D%3D%26mid%3D2247485292%26idx%3D1%26sn%3D202b462d96b42055baaa348c81cc9fe1%26chksm%3De8f176dcdf86ffcab70664f851419015ea382067f74d08af528ab403831dcf3ee17519fe5229%26scene%3D21%23wechat_redirect)

MySQL是怎么读数据的——多版本并发控制

本文分享自微信公众号 - MySQL数据库技术栈(Mysqltechnology)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
4个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这