1 LVS 介绍
1.1 简介
LVS 是 Linux Virtual Server 的简写,意即 Linux 虚拟服务器,是一个虚拟的服务器集群系统。本项目在 1998 年 5 月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。
LVS 集群采用 IP 负载均衡技术和基于内容请求分发技术。调度器具有很好的吞吐率,将请求均衡地转移到不同的服务器上执行,且调度器自动屏蔽掉服务器的故障,从而将一组服务器构成一个高性能的、高可用的虚拟服务器。
比如说,用 LVS 做 Web 负载均衡,那么请求 LVS 调度器的时候,请求会根据配置的算法分发给后端某台 Web 服务器,后端 Web 服务器机器对于请求者来说是透明的。
1.1 LVS 工作模式
LVS 包含以下三种常用工作模式
1). NAT 模式
NAT (Network Address Translation) 即网路地址装换,NAT 的工作原理是更改报文头(目标地址、源地址和端口等)后,转发请求都后端地址。流程如下
- 客户端请求 LVS 的 IP
- LVS 更改请求的目的 IP,改为后端服务器其中一个 IP,然后转发请求
- 后端服务器处理完,返回数据给 LVS,LVS 更改源 IP 为 LVS 机器的 IP 然后返回给请求端
NAT 模式的所有数据都会经过 LVS 服务器,简单来说就是从 LVS 进,从 LVS 出,如图
2). TUN 模式
在 NAT 的集群系统中,请求和响应的数据报文都需要通过 LVS 服务器,当真实服务器的数目在10台和20台之间时,负载调度器将成为整个集群系统的新瓶颈。大多数 Internet服务都有这样的特点:请求报文较短而响应报文往往包含大量的数据。如果能将请求和响应分开处理,即在负载调度器中只负责调度请求而响应直接返回给客户,将极大地提高整个集群系统的吞吐量。
IP 隧道(IP tunneling)是将一个IP报文封装在另一个IP报文的技术,这可以使得目标为一个IP地址的数据报文能被封装和转发到另一个IP地址。IP隧道技 术亦称为IP封装技术(IP encapsulation)。IP隧道主要用于移动主机和虚拟私有网络(Virtual Private Network),在其中隧道都是静态建立的,隧道一端有一个IP地址,另一端也有唯一的IP地址。
我们利用IP隧道技术将请求报文封装转发给后端服务器,响应报文能从后端服务器直接返回给客户(要求后端真实服务器与外部网络连接)。
TUN 模式工作流程如下:
- 客户端请求数据,调度器根据各个服务器的负载情况,动态地选择一台服务器, 将请求报文封装在另一个IP报文中,再将封装后的IP报文转发给选出的服务器
- 服务器收到报文后,先将报文解封获得原来目标地址为VIP的报文,服务器发 现VIP地址被配置在本地的IP隧道设备上,所以就处理这个请求,然后根据路由表将响应报文直接返回给客户。
3). DR 模式
DR 模式中,负载调度器中只负责调度请求,而服务器直接将响应返回给客户, DR 模式架构图
DR 模式的执行流程如下
- 客户端请求数据,调度器根据各个服务器的负载情况,动态地选择一台服务器,不修改也不封装IP报文,而是将数据帧的MAC 地址改为选出服务器的 MAC 地址,再将修改后 的数据帧在与服务器组的局域网上发送。
- 因为数据帧的 MAC 地址是选出的服务器,所以服务器肯定可以收到这个数据帧,从中可以获得该 IP 报文。当服务器发现 报文的目标地址VIP是在本地的网络设备上,服务器处理这个报文,然后根据路由表将响应报文直接返回给客户。
关于三种模式选择
NAT
模式下,所有流量会经过 LVS
服务器, 很容易有瓶颈;TUN
模式需要内核支持,部署成本比较高;DR
模式性能高、容易部署,一般使用这种模式。
本小节内容参考: LVS集群中的IP负载均衡技术
1.2 LVS 调度算法
这里简单介绍 LVS 的 8 种调度算法
静态调度
- 轮询调度(rr): 轮询调就是依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。
- 加权轮询(wrr): 加权轮询算法可以解决服务器间性能不一的情况,它用相应的权值表示服务器的处理性能,服务器的缺省权值为1。假设服务器A的权值为1,B的 权值为2,则表示服务器B的处理性能是A的两倍。加权轮询调度算法是按权值的高低和轮叫方式分配请求到各服务器。
- 源地址散列(sh): 该算法正好与目标地址散列调度算法相反,它根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。
- 目标地址散列(dh): 该算法也是针对目标IP地址的负载均衡,但它是一种静态映射算法,通过一个散列(Hash)函数将一个目标IP地址映射到一台服务器。
动态调度
- 最少连接(lc): 最少连接是把新的连接请求分配到当前连接数最小的服务器。
- 加权最少连接(wlc): 加权最少连接算法是最小连接调度的超集,各个服务器用相应的权值表示其处理性能。
- 基于局部性的最少连接(lblc): 该算法是针对请求报文的目标IP地址的负载均衡调度,目前主要用于Cache集群系统,因为在Cache集群中 客户请求报文的目标IP地址是变化的。
- 带复制的基于局部性最少连接(lblcr): 该算法也是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。它与LBLC算法的不同之处是它要 维护从一个目标IP地址到一组服务器的映射,而LBLC算法维护从一个目标IP地址到一台服务器的映射。
本小节内容参考: LVS集群的负载调度
2 Keepalived 简介
Keepalived 起初是为 LVS 件设计, 用来管理和监控 LVS 各个服务器节点状态的工具
Keepalived 采用 Master/Slave 模式, 在 Master 上设置配置文件的 VIP,当 Master 宕机后,VIP 自动漂移到另一台 Keepalived 服务器上
Keepalived 可以用来做各种软件的高可用集群,它会一直检测服务器的状态,如果有一台服务器宕机,或工作出现故障,Keepalived 将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后 Keepalived 自动将服务器加入到服务器群中。
简单来说,Keepalived 就是用来实现机器的高可用的,在使用 Keepalived 的情况下,只有一台服务器能够提供服务(通过 VIP 来实现),当 Master 主机宕机后,VIP 会自动飘移到另一台服务器
3 环境准备
3.1 服务器与 mysql 环境
MySQL 环境采用上篇文章部署的那一套,然后新增一台服务器作为 LVS 的备用节点
节点信息
IP | 系统 | 端口 | MySQL版本 | 节点 | 读写 | 说明 |
---|---|---|---|---|---|---|
10.0.0.247 | Centos6.5 | 3306 | 5.7.9 | Master | 读写 | 主节点 |
10.0.0.248 | Centos6.5 | 3306 | 5.7.9 | Standby | 只读,可切换为读写 | 备主节点 |
10.0.0.249 | Centos6.5 | 3306 | 5.7.9 | Slave | 只读 | 从节点 |
10.0.1.24 | Centos6.5 | - | - | MMM Monitor/LVS | - | MMM Monitor/LVS Keepalive Master |
10.0.1.85 | Centos6.5 | - | - | LVS | - | LVS Keepalive Slave |
VIP 信息
简称 | VIP | 类型 |
---|---|---|
RW-VIP | 10.0.0.237 | 读写VIP |
RO-VIP1 | 10.0.0.238 | 读VIP |
RO-VIP2 | 10.0.0.239 | 读VIP |
LVS-RO | 10.0.0.236 | LVS Keepalived VIP |
3.2 Keepalved 安装配置
我们在10.0.1.24
和10.0.1.85
上部署 Keepalived
1). yum 安装
如果有对应的 yum
源,直接安装就可以了
yum install -y keepalived
2). 源码安装
下载安装包, 下载地址 keepalived, 使用 1.2.24
版本举例
# 安装依赖
yum install -y gcc popt-devel openssl openssl-devel libssl-dev libnl-devel popt-devel libnfnetlink-devel
# 下载包
wget http://www.keepalived.org/software/keepalived-1.2.24.tar.gz
# 解压安装
tar -xvz -f keepalived-1.2.24.tar.gz
cd keepalived-1.2.24
./configure --prefix=/usr/local/keepalived
make && make install
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
mkdir /etc/keepalived/
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
3). 配置 Keepalived
打开 /etc/keepalived/keepalived.conf
文件, 加上上面的配置
global_defs {
notification_email {
}
router_id MYSQL_MMM
}
vrrp_instance MMM_TEST {
state BACKUP
interface eth0
virtual_router_id 24
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.236
}
}
router_id
: 标识用的state
:MASTER
或BACKUP
, 当其他节点起来的时候会重新选举,所以这里设为BACKUP
就可以了virtual_router_id
: 用来区分VRRP
组播的标记,取值 0-255priority
: 优先级advert_int
: 监控检测间隔authentication
: 认证相关virtual_ipaddress
: 要设置的VIP
注意: 在同一个广播域内 virtual_router_id 不能重复
4). 启动
由于在priority
都相同,所以先启动为 Master
, 我们在10.0.1.24
和10.0.1.85
上轮流启动Keepalived
/etc/init.d/keepalived start
启动后观察10.0.1.24
IP
状态
[root@chengqm ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether fa:16:3e:ee:ae:a1 brd ff:ff:ff:ff:ff:ff
inet 10.0.1.24/16 brd 10.0.255.255 scope global eth0
inet 10.0.0.236/32 scope global eth0
inet6 fe80::f816:3eff:feee:aea1/64 scope link
valid_lft forever preferred_lft forever
3.3 LVS 安装配置
本次测试,负载调度的算法采用 加权最少连接(wlc)
,工作模式采用 DR
模式
1). 安装
LVS
采用 yum
安装就可以了
yum install -y ipvsadm
2). 增加配置文件
继续打开 /etc/keepalived/keepalived.conf
文件, 在后面加上 LVS
配置, 转发VIP
为10.0.0.236
的3306
端口到MMM
的虚IP
virtual_server 10.0.0.236 3306 {
delay_loop 6 # 健康检查时间,单位是秒
lb_algo wlc # 负载调度的算法
lb_kind DR # LVS 工作模式
nat_mask 255.255.255.255 # 掩码
persistence_timeout 0
protocol TCP
real_server 10.0.0.237 3306 { # 指定后端真实服务器的IP地址, 这里直接指到 MMM 虚 IP 上
weight 1 # 节点权重, 数字越大, 权重越大
TCP_CHECK { # 检测参数
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 3306
}
}
real_server 10.0.0.238 3306 {
weight 3
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 3306
}
}
real_server 10.0.0.239 3306 {
weight 3
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 3306
}
}
}
更改完毕重启 keepalived
3). 后端真实服务器抑制 ARP 广播
由于 DR 模式的原理是 LVS
与后端真实服务器配置同一个 VIP
,后端服务器 不允许arp
广播,这样路由器接收到请求就会发给 LVS
,LVS
修改请求的 MAC
地址。这样路由器和后端服务器通过 MAC
地址进行通信,达到负载均衡的目的。
在 10.0.0.247
, 10.0.0.248
, 10.0.0.249
服务器上执行以下命令
VIP=10.0.0.236
ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP
/sbin/route add -host $VIP dev lo:0
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 >/dev/null 2>&1
注意: 后端真实服务器的 VIP 绑在 lo 上
如果想取消,可以反着操作
ifconfig lo:0 down
route del VIP >/dev/null 2>&1
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
4). 检查 LVS 状态
[root@chengqm ~]# ipvsadm -l
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.0.0.236:mysql wlc
-> 10.0.0.237:mysql Route 1 0 0
-> 10.0.0.238:mysql Route 3 0 0
-> 10.0.0.239:mysql Route 3 0 0
LVS
负载均衡已经生效
4 测试
4.1 负载均衡测试
LVS 配置好了,让我们测试一下效果, 目前 Keepalived
Master
在 10.0.1.24
, 并且已经预先创建了一个测试账号,那么我们在其他机器发起请求看看
[root@mysql-test-83 ~]# mysql -umytest -p -h10.0.0.236 -P3306 -e "show variables like \'hostname\'"
Enter password:
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| hostname | cluster01 |
+---------------+-----------+
[root@mysql-test-83 ~]# mysql -umytest -p -h10.0.0.236 -P3306 -e "show variables like \'hostname\'"
Enter password:
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| hostname | cluster02 |
+---------------+-----------+
可以看到,LVS 负载均衡已经生效
4.2 高可用测试
10.0.1.24
和 10.0.1.85
部署了 Keepalived
服务,我们停掉Master
的Keepalived
, VIP 会自动飘移到另一台机器
现在停掉10.0.1.24
的Keepalived
[root@chengqm ~]# /etc/init.d/keepalived stop
Stopping keepalived: [ OK ]
查看10.0.1.85
的IP
[root@yexm ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether fa:16:3e:3c:81:1b brd ff:ff:ff:ff:ff:ff
inet 10.0.1.85/16 brd 10.0.255.255 scope global eth0
inet6 fe80::f816:3eff:fe3c:811b/64 scope link
valid_lft forever preferred_lft forever
[root@yexm ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether fa:16:3e:3c:81:1b brd ff:ff:ff:ff:ff:ff
inet 10.0.1.85/16 brd 10.0.255.255 scope global eth0
inet 10.0.0.236/32 scope global eth0
inet6 fe80::f816:3eff:fe3c:811b/64 scope link
valid_lft forever preferred_lft forever
可以看到 VIP
已经飘移到另一台 LVS
服务器
5 结语
LVS
+ MMM
下既可以实现多台 MySQL
节点的负载均衡,也避免了因为同步延迟、同步失败等问题造成的数据不一致问题,是一个非常不错的架构方式。