前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Keepalived+LVS+MySQL双主复制实现读写负载均衡及高可用

Keepalived+LVS+MySQL双主复制实现读写负载均衡及高可用

作者头像
用户1148526
发布2019-05-25 19:34:28
2K0
发布2019-05-25 19:34:28
举报
文章被收录于专栏:Hadoop数据仓库

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1433047

目录

一、Keepalived和LVS简介

1. Keepalived简介

2. LVS简介

二、安装配置

1. 下载安装LVS

2. 下载安装Keepalived

3. Keepalived配置

5. 编写RealServer的网络配置脚本

三、测试

四、总结

参考:


代码语言:txt
复制
    上一篇我们使用Keepalived的HA功能,实现MySQL主从复制的自动故障切换。它的工作原理是:初始将MySQL的主从两个主机赋予不同的优先级别,当Keepalived启动时,会将VIP绑定到高优先级的主库上。在Keepalived中调用自定义脚本check\_run,每分钟检查一次本机MySQL的服务器状态,如果MySQL不可用,则杀掉本机的keepalived进程。Keepalived每秒钟会检查一次本机的keepalived进程,如果进程不存在,则将VIP绑定到另一台机器上,如果这台机器原来是从库,则同时调用master.sh脚本执行从库切换为主库的操作。
代码语言:txt
复制
     本篇我们将做另一个实验,利用Keepalived的IPVS功能,调用LVS实现MySQL双主复制的读写负载均衡,同时保证负载均衡器和MySQL的高可用性。实验环境如图1所示。

图1

一、Keepalived和LVS简介

1. Keepalived简介

代码语言:txt
复制
    参见“[使用Keepalived实现MySQL主从高可用](https://blog.csdn.net/wzy0623/article/details/80916567)”。

2. LVS简介

代码语言:txt
复制
    LVS(Linux Virtual Server)是一个高可用性虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。LVS主要用于多服务器的负载均衡,作用于网络层。LVS构建的服务器集群系统中,前端的负载均衡层被称为Director Server,后端提供服务的服务器组层被称为Real Server。通过下图可以大致了解LVS的基础架构。

图2

代码语言:txt
复制
     LVS由ipvs和ipvsadm两部分组成:
  • ipvs:ipvs是工作在内核空间netfilter的input链上的框架,通过用户空间工具进行管理,其中是真正生效实现调度的代码。
  • ipvsadm:ipvsadm负责为ipvs内核框架编写规则,是管理配置内核中ipvs程序的用户空间的管理工具。
代码语言:txt
复制
    LVS是工作在linux内核空间的tcp/ip栈的应用程序,其程序名称为ipvs。ipvs会监听input链上的请求,一旦请求的是集群服务的话,ipvs钩子函数会将请求拉出并进行报文修改,强制转发到postrouting处理,关系如图3所示。

图3

代码语言:txt
复制
     在客户端看来,LVS就是一个真实的应用服务器。客户端向LVS发送请求信息,LVS接收数据报文至内核空间,工作在input链上的ipvs模块会判断用户请求是不是定义的后端服务器,如果用户请求的就是定义的后端集群服务,数据报文传送到input链上时,input链会强行将数据报文转发给postrouting,postrouting将数据报文传送给后端真实服务器。LVS的特点在于超强的分流功能,但它只能负责调度流量的去向,没有办法实现在业务层分流负载。
代码语言:txt
复制
     LVS可以独立使用,但更普遍的做法是与Keepalived一起使用。LVS提供负载均衡,Keepalived提供健康检查,故障转移,提高系统的可用性。Keepalived中的LVS配置包括虚拟主机组(Virtual Server Group)和虚拟主机(Virtual Server)。这些配置会传递给ipvsadm作为参数。采用这样的架构以后,很容易对现有系统进行扩展,在后端添加或者减少realserver后,只需要更改Keepalived配置文件中的LVS部分即可。

二、安装配置

代码语言:txt
复制
    环境:

172.16.1.124:Keepalived + LVS Master

172.16.1.125:Keepalived + LVS Slave

172.16.1.126:MySQL Replication Master

172.16.1.127:MySQL Replication Master

172.16.1.100:VIP

代码语言:txt
复制
     在本环境中的RealServer就是两台MySQL服务器,LVS和RealServer分别使用两台主机。当LVS架构中的Director Server和RealServer工作在同一台机器上时,需要注意SYN\_RECV问题,即会出现两台director无限循环转发请求的情况。对该问题的讨论参见“[怎么样让LVS和realserver工作在同一台机器上](http://www.360doc.com/content/14/0919/10/1123425_410633433.shtml)”。
代码语言:txt
复制
     在172.16.1.126和172.16.1.127上配置MySQL双主复制,详细步骤从略。与主从复制相比,双主复制需要注意以下三个参数的设置:
  • log_slave_updates:要设置为true,将复制事件写入本机binlog。一台服务器既做主库又做从库时此选项必须要开启。
  • auto_increment_offset和auto_increment_increment:为避免自增列冲突,需要设置这两个参数,例如在双主复制中,可以配置如下: # masterA自增长ID auto_increment_offset = 1 auto_increment_increment = 2 #奇数ID # masterB自增加ID auto_increment_offset = 2 auto_increment_increment = 2 #偶数ID

1. 下载安装LVS

代码语言:txt
复制
    在172.16.1.124和172.16.1.125上用root用户执行以下命令:
代码语言:javascript
复制
yum -y install ipvsadm

2. 下载安装Keepalived

代码语言:txt
复制
    在172.16.1.124和172.16.1.125上安装Keepalived,详细步骤参见“[使用Keepalived实现MySQL主从高可用](https://blog.csdn.net/wzy0623/article/details/80916567)”。

3. Keepalived配置

代码语言:txt
复制
    172.16.1.124初始为keepalived的master,其上的keepalived配置文件如下:
代码语言:javascript
复制
[root@hdp1~]#more /etc/keepalived/keepalived.conf 
global_defs {
   router_id LVS_DEVEL
} 
 
vrrp_sync_group VG1 {
group {
VI_1
}
}
 
vrrp_instance VI_1 {
    state BACKUP
    interface ens32 
    virtual_router_id 51
    priority 100  
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1234
    }
    virtual_ipaddress {
        172.16.1.100
    }
}

virtual_server 172.16.1.100 3306 {	# 定义虚拟服务器,地址与上面的virtual_ipaddress相同
    delay_loop 3			        # 健康检查时间间隔,3秒
    lb_algo rr				        # 负载均衡调度算法:rr|wrr|lc|wlc|sh|dh|lblc
    lb_kind DR				        # 负载均衡转发规则:NAT|DR|TUN
    # persistence_timeout 5	        # 会话保持时间5秒,动态服务建议开启
    protocol TCP			        # 转发协议protocol,一般有tcp和udp两种
 
    #后端真实服务器,有几台就设置几个
    real_server 172.16.1.126 3306 {
        weight 1			        # 权重越大负载分越大,0表示失效
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
    real_server 172.16.1.127 3306 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
}

[root@hdp1~]#
代码语言:txt
复制
    172.16.1.125初始为keepalived的slave,其上的keepalived配置文件如下:
代码语言:javascript
复制
[root@hdp2~]#more /etc/keepalived/keepalived.conf 
global_defs {
   router_id LVS_DEVEL
} 
 
vrrp_sync_group VG1 {
group {
VI_1
}
}
 
vrrp_instance VI_1 {
    state BACKUP
    interface ens32 
    virtual_router_id 51
    priority 90  
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1234
    }
    virtual_ipaddress {
        172.16.1.100
    }
}

virtual_server 172.16.1.100 3306 {	# 定义虚拟服务器,地址与上面的virtual_ipaddress相同
    delay_loop 3			        # 健康检查时间间隔,3秒
    lb_algo rr				        # 负载均衡调度算法:rr|wrr|lc|wlc|sh|dh|lblc
    lb_kind DR				        # 负载均衡转发规则:NAT|DR|TUN
    # persistence_timeout 5	        # 会话保持时间5秒,动态服务建议开启
    protocol TCP			        # 转发协议protocol,一般有tcp和udp两种
 
    #后端真实服务器,有几台就设置几个
    real_server 172.16.1.126 3306 {
        weight 1			        # 权重越大负载分越大,0表示失效
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
    real_server 172.16.1.127 3306 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
}

[root@hdp2~]#
代码语言:txt
复制
    master与slave的keepalived配置文件中只有priority设置不同,master为100,slave为90,其它全一样。配置文件是以块形式组织的,每个块都在{}包围的范围内,#和!开头的行都是注释。global\_defs、vrrp\_sync\_group、vrrp\_instance部分的配置说明参见“[使用Keepalived实现MySQL主从高可用](https://blog.csdn.net/wzy0623/article/details/80916567)”。
代码语言:txt
复制
     本例中没有配置virtual\_server\_group。该配置段是可选的,目的是为了让一台RealServer的某个Service可以属于多个Virtual Server,并且只做一次健康检查。下面重点说明virtual server段的配置。
  • virtual_server:设置一个虚拟服务器,指定其虚拟IP和虚拟端口。
  • delay_loop:指定服务轮询的时间间隔,单位是秒。
  • lb_algo:指定LVS的调度算法,本例指定为rr,即轮询。关于LVS所支持调度算法的说明,参见http://www.cnblogs.com/anay/p/9260306.html#_label7
  • lb_kind:指定LVS转发模式,本例设置为DR,这也是大多数生产环境的配置。关于LVS所支持转发模式的说明,参见http://www.cnblogs.com/anay/p/9260306.html#_label3
  • persistence_timeout:指定以秒为单位的会话保持时间,这里做了注释,意为不保持,目的是为了方便查看后面测试rr负载均衡算法的效果。生产环境建议开启该参数。
  • protocol:指定转发协议使用TCP还是UDP。
  • real_server:每台RealServer都需要一个real_server配置项,执行真实服务器的IP和端口。本例指定两个MySQL库的服务器地址和端口。
  • weight:指定RealServer权重,默认为1,0为失效。
  • TCP_CHECK:指定健康检查方式为TCP。支持HTTP_GET、SSL_GET、TCP_CHECK、SMTP_CHECK、MISC_CHECK、HTTP_GET、SSL_GET等检查方式,每种方式包含自己的参数。
  • connect_timeout:定义连接超时时间,单位是秒。
  • nb_get_retry:指定重连次数。
  • delay_before_retry:指定重连的时间间隔,单位是秒。
  • connect_port:指定健康检查的端口。

5. 编写RealServer的网络配置脚本

代码语言:txt
复制
    在172.16.1.126和172.16.1.127上建立/etc/init.d/realserver文件,内容如下:
代码语言:javascript
复制
#!/bin/sh
VIP=172.16.1.100
. /etc/rc.d/init.d/functions

case "$1" in
# 禁用本地的ARP请求、绑定本地回环地址
start)
    /sbin/ifconfig lo down
    /sbin/ifconfig lo up
    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
    /sbin/sysctl -p >/dev/null 2>&1
    /sbin/ifconfig lo:0 $VIP netmask 255.255.255.255 up # 在回环地址上绑定VIP,设定掩码,与Direct Server上自身的IP保持通信
    /sbin/route add -host $VIP dev lo:0
    echo "LVS-DR real server starts successfully.\n"
    ;;
stop)
    /sbin/ifconfig lo:0 down
    /sbin/route del $VIP >/dev/null 2>&1
    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
echo "LVS-DR real server stopped.\n"
    ;;
status)
    isLoOn=`/sbin/ifconfig lo:0 | grep "$VIP"`
    isRoOn=`/bin/netstat -rn | grep "$VIP"`
    if [ "$isLoON" == "" -a "$isRoOn" == "" ]; then
        echo "LVS-DR real server has run yet."
    else
        echo "LVS-DR real server is running."
    fi
    exit 3
    ;;
*)
    echo "Usage: $0 {start|stop|status}"
    exit 1
esac
exit 0
代码语言:txt
复制
    执行下面的命令将该脚本加入开机自启动:
代码语言:javascript
复制
chmod +x /etc/init.d/realserver
echo "/etc/init.d/realserver" >> /etc/rc.d/rc.local
代码语言:txt
复制
    执行以下命令配置realserver:
代码语言:javascript
复制
service realserver start
代码语言:txt
复制
    命令执行后172.16.1.126和172.16.1.127上的IP地址分别如图4、5所示。

图4

图5

三、测试

  1. 分别在master上和slave上启动keepalived进程。 在172.16.1.124和172.16.1.125上执行以下命令:
代码语言:javascript
复制
/etc/init.d/keepalived start
  1. 查看master和slave上的VIP 结果分别如图6、7所示,可以看到VIP已经成功绑定到172.16.1.124。

图6

图7

代码语言:txt
复制
     此时查看LVS集群状态,可以看到集群下有两个RealServer,调度算法,权重等信息。ActiveConn代表当前RealServer的活跃连接数。
代码语言:javascript
复制
[root@hdp1~]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.16.1.100:3306 rr
  -> 172.16.1.126:3306            Route   1      0          0         
  -> 172.16.1.127:3306            Route   1      0          0         
[root@hdp1~]#
  1. 验证LVS负载均衡转发策略 MySQL客户端使用VIP连接数据库,并查看所连接的数据库服务器ID。可以看到,每次执行依次连接到172.16.1.126和172.16.1.127的MySQL,证明是轮询策略产生的结果。
代码语言:javascript
复制
C:\WINDOWS\system32>mysql -uwxy -p123456 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 126   |
+---------------+-------+

C:\WINDOWS\system32>mysql -uwxy -p123456 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 127   |
+---------------+-------+

C:\WINDOWS\system32>mysql -uwxy -p123456 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 126   |
+---------------+-------+

C:\WINDOWS\system32>mysql -uwxy -p123456 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 127   |
+---------------+-------+
  1. 模拟LVS的master失效 停止master上的keepalived服务,在172.16.1.124上执行以下命令:
代码语言:javascript
复制
/etc/init.d/keepalived stop
代码语言:txt
复制
    再次查看172.16.1.124、172.16.1.125绑定的VIP分别如图8、9所示。可以看到VIP已经漂移到172.16.1.125上,它成为了新的master。

图8

图9

代码语言:txt
复制
     此时连接MySQL,负载均衡不受影响。
代码语言:javascript
复制
C:\WINDOWS\system32>mysql -uwxy -p123456 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 127   |
+---------------+-------+

C:\WINDOWS\system32>mysql -uwxy -p123456 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 126   |
+---------------+-------+

C:\WINDOWS\system32>mysql -uwxy -p123456 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 127   |
+---------------+-------+

C:\WINDOWS\system32>mysql -uwxy -p123456 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 126   |
+---------------+-------+
代码语言:txt
复制
    此时再次启动172.16.1.124上keepalived服务,它已经变为slave,而且并不会去抢占master,这是由nopreempt参数决定的。
  1. 模拟mysqld crash 在172.16.1.126上执行以下命令:
代码语言:javascript
复制
pkill -9 mysqld
代码语言:txt
复制
    此时,LVS检测到了172.16.1.126上的MySQL Server宕机,集群自动剔除了故障节点。此时集群中只有一个RealServer的地址,即172.16.1.127:3306。
代码语言:javascript
复制
[root@hdp1~]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.16.1.100:3306 rr
  -> 172.16.1.127:3306            Route   1      0          0         
[root@hdp1~]#
代码语言:txt
复制
    此时连接MySQL,可以看到应用不受影响,但只连接到一台MySQL服务器。
代码语言:javascript
复制
C:\WINDOWS\system32>mysql -uwxy -p123456 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 127   |
+---------------+-------+

C:\WINDOWS\system32>mysql -uwxy -p123456 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 127   |
+---------------+-------+

C:\WINDOWS\system32>mysql -uwxy -p123456 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 127   |
+---------------+-------+

C:\WINDOWS\system32>mysql -uwxy -p123456 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 127   |
+---------------+-------+
代码语言:txt
复制
    重新启动172.16.1.126上的MySQL后,LVS自动将故障节点自动加入集群。
代码语言:javascript
复制
[root@hdp1~]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.16.1.100:3306 rr
  -> 172.16.1.126:3306            Route   1      0          0         
  -> 172.16.1.127:3306            Route   1      0          0         
[root@hdp1~]#

四、总结

  1. 之所以要使用MySQL双主复制而不是主从复制,是因为本方案中并没有涉及读写分离,而是在两个等价的MySQL服务器之间做读写负载均衡。
  2. 本例中除了简单配置外,没有任何自定义的脚本。
  3. Keepalived利用VRRP实现了LVS的HA,避免了LVS服务器的单点故障,出现故障时可以自动切换到正常的节点。
  4. LVS服务器提供了负载均衡的作用,将用户请求分发到多个RealServer。同时,一台RealServer故障并不会影响整个集群,因为LVS会检测RealServer的状态,并据此自动添加或删除集群中的RealServer服务。
  5. 如本例的配置,需要考虑单台MySQL服务器的负载最好不要超过50%,否则一旦某台MySQL服务器故障,可能出现另一台正常MySQL不堪重负的情况。

参考:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年07月12日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Keepalived和LVS简介
    • 1. Keepalived简介
      • 2. LVS简介
      • 二、安装配置
        • 1. 下载安装LVS
          • 2. 下载安装Keepalived
            • 3. Keepalived配置
              • 5. 编写RealServer的网络配置脚本
              • 三、测试
              • 四、总结
              • 参考:
              相关产品与服务
              云数据库 SQL Server
              腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档