ITPub博客

首页 > 数据库 > MySQL > MySQL高可用----双主+Keepalived+LVS--单点故障、故障切换、负载均衡

MySQL高可用----双主+Keepalived+LVS--单点故障、故障切换、负载均衡

原创 MySQL 作者:lhrbest 时间:2020-02-21 19:27:11 0 删除 编辑

MySQL高可用----双主+Keepalived+LVS--单点故障、故障切换、负载均衡


LVS Linux Virtual Server )是一个高可用性虚拟的服务器集群系统。本项目在 1998 5 月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。 LVS 主要用于多服务器的负载均衡,作用于网络层。 LVS 构建的服务器集群系统中,前端的负载均衡层被称为 Director Server ,后端提供服务的服务器组层被称为 Real Server

利用Keepalived IPVS 功能,调用 LVS 实现 MySQL 双主复制的读写负载均衡,同时保证负载均衡器和 MySQL 的高可用性。




 

一.1   MySQL 双主+ GTID 环境安装

与主从复制相比,双主复制需要注意以下三个参数的设置:

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

 

/usr/local/mysql57/mysql5719/bin/mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql57/mysql5719 --datadir=/usr/local/mysql57/mysql5719/data573332131
/usr/local/mysql57/mysql5719/bin/mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql57/mysql5719 --datadir=/usr/local/mysql57/mysql5719/data573332132
 
vi /etc/my.cnf
 
 
### MySQL双主+Keepalived+LVS
#  M1(131)  <---->  M2(132)
 
#M1
[mysqld573332131]
basedir=/usr/local/mysql57/mysql5719
datadir=/usr/local/mysql57/mysql5719/data573332131
socket=/usr/local/mysql57/mysql5719/data573332131/mysqld573332131.sock
log-error=/usr/local/mysql57/mysql5719/data573332131/mysqld573332131.log
user=mysql
port=3332
character_set_server=utf8mb4
secure_file_priv=''
server-id = 573332131
log-bin =
binlog_format=STATEMENT
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
replicate_ignore_db=information_schema
replicate_ignore_db=performance_schema
replicate_ignore_db=mysql
replicate_ignore_db=sys
log-slave-updates
auto-increment-increment=2
auto-increment-offset=1
skip_name_resolve
gtid-mode=ON
enforce-gtid-consistency=on
 
 
 
### MySQL双主+Keepalived+LVS
#  M1(131)  <---->  M2(132)
#M2
[mysqld573332132]
basedir=/usr/local/mysql57/mysql5719
datadir=/usr/local/mysql57/mysql5719/data573332132
socket=/usr/local/mysql57/mysql5719/data573332132/mysqld573332132.sock
log-error=/usr/local/mysql57/mysql5719/data573332132/mysqld573332132.log
user=mysql
port=3332
character_set_server=utf8mb4
secure_file_priv=''
server-id = 573332132
log-bin =
binlog_format=STATEMENT
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
replicate_ignore_db=information_schema
replicate_ignore_db=performance_schema
replicate_ignore_db=mysql
replicate_ignore_db=sys
log-slave-updates
auto-increment-increment=2
auto-increment-offset=2
skip_name_resolve
gtid-mode=ON
enforce-gtid-consistency=ON
 
 
mysqld_multi start 573332131-573332132
mysqld_multi report 573332131-573332132
 
mysql -uroot -p -S/usr/local/mysql57/mysql5719/data573332131/mysqld573332131.sock
mysql -uroot -p -S/usr/local/mysql57/mysql5719/data573332132/mysqld573332132.sock
 
 
 
grant all privileges on *.* to root@'%' identified by 'lhr'  WITH GRANT OPTION;
grant all privileges on *.* to root@'localhost' identified by 'lhr'  WITH GRANT OPTION;
flush privileges;
select user,host,grant_priv from mysql.user;
 
 
 
--2个主库
grant replication slave on *.* to repl@'%' identified by 'lhr';
 
show master status \G;
 
 
--M2
change master to master_host='192.168.59.131',master_port=3332,master_user='repl',master_password='lhr',master_auto_position=1;
 
--M1
change master to master_host='192.168.59.132',master_port=3332,master_user='repl',master_password='lhr',master_auto_position=1;
 
 
 
 
start slave;
show slave status \G;
 
 
--主库
create database lhrdb;
use lhrdb;
create table lhrdb.mytb1(id int,name varchar(30));
SET SESSION binlog_format = 'STATEMENT';
insert into lhrdb.mytb1 values(1,@@hostname);
select * from lhrdb.mytb1;

 

 

一.2   安装keepalived 软件包

下载:

http://www.keepalived.org/software/

http://rpmfind.net/linux/rpm2html/search.php?query=keepalived&submit=%E6%90%9C%E7%B4%A2...+&system=&arch=

 

安装Keepalived 并将其配置成系统服务。 133 134 两台机器上同样进行如下操作:

yum install -y openssl-devel
cd /soft
wget http://www.keepalived.org/software/keepalived-2.0.19.tar.gz
tar -zvxf keepalived-2.0.19.tar.gz
cd keepalived-2.0.19
./configure --prefix=/usr/local/keepalived
make && make install
 
--或:yum install -y keepalived
 
cp /soft/keepalived-2.0.19/keepalived/etc/init.d/keepalived /etc/rc.d/init.d/
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
mkdir /etc/keepalived/
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
echo "/etc/init.d/keepalived start" >> /etc/rc.local
chkconfig keepalived on

 

 

 

一.3   下载安装LVS

133 134 两台机器上同样进行如下操作:

yum -y install ipvsadm

 

一.4   keepalived 配置

一.4.1   133 上配置

[root@master1 ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak

[root@master 1  ~]# echo '' > /etc/keepalived/keepalived.conf

[root@master1 ~]# vim /etc/keepalived/keepalived.conf        #清空默认内容,直接采用下面配置:

 

global_defs {

   router_id LVS_DEVEL

}

 

vrrp_sync_group VG1 {

group {

VI_1

}

}

 

vrrp_instance VI_1 {

    state BACKUP

    interface  eth0

    virtual_router_id 51

    priority 100  

    advert_int 1

    nopreempt

    authentication {

        auth_type PASS

        auth_pass 1234

    }

    virtual_ipaddress {

         192.168.59.136

    }

}

 

virtual_server 192.168.59.136 3332  { # 定义虚拟服务器,地址与上面的 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 192.168.59.131 3332  {

        weight 1           # 权重越大负载分越大, 0 表示失效

        TCP_CHECK {

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

            connect_port 3332

        }

    }

    real_server 192.168.59.132 3332  {

        weight 1

        TCP_CHECK {

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

            connect_port 3332

        }

    }

}

 

 

 

一.4.2   134 上配置

[root@master1 ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak

[root@master 1  ~]# echo '' > /etc/keepalived/keepalived.conf

[root@master1 ~]# vim /etc/keepalived/keepalived.conf        #清空默认内容,直接采用下面配置:

 

global_defs {

   router_id LVS_DEVEL

}

 

vrrp_sync_group VG1 {

group {

VI_1

}

}

 

vrrp_instance VI_1 {

    state BACKUP

    interface  eth0

    virtual_router_id 51

    priority 90   

    advert_int 1

    nopreempt

    authentication {

        auth_type PASS

        auth_pass 1234

    }

    virtual_ipaddress {

         192.168.59.136

    }

}

 

virtual_server 192.168.59.136 3332  { # 定义虚拟服务器,地址与上面的 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 192.168.59.131 3332  {

        weight 1           # 权重越大负载分越大, 0 表示失效

        TCP_CHECK {

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

            connect_port 3332

        }

    }

    real_server 192.168.59.132 3332  {

        weight 1

        TCP_CHECK {

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

            connect_port 3332

        }

    }

}

 

133 134 keepalived 配置文件中只有 priority 设置不同, master 100 slave 90 ,其它全一样。


 

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

131 132 上建立 /etc/init.d/realserver 文件,内容如下:

#!/bin/sh
VIP=192.168.59.136
. /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

 

执行下面的命令将该脚本加入开机自启动:

chmod +x /etc/init.d/realserver

echo "/etc/init.d/realserver" >> /etc/rc.d/rc.local

执行以下命令配置realserver

service realserver start

结果:

[root@Master1-ip131 keepalived]$ service realserver start

LVS-DR real server starts successfully.\n

[root@Master1-ip131 keepalived]$

[root@Master1-ip131 keepalived]$

[root@Master1-ip131 keepalived]$

[root@Master1-ip131 keepalived]$ ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 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

    inet 192.168.59.136/32 brd 192.168.59.136 scope global lo:0

    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 00:0c:29:e7:e4:a6 brd ff:ff:ff:ff:ff:ff

    inet 192.168.59.131/24 brd 192.168.59.255 scope global eth0

    inet 192.168.59.135/24 brd 192.168.59.255 scope global secondary eth0:1

    inet6 fe80::20c:29ff:fee7:e4a6/64 scope link

       valid_lft forever preferred_lft forever

 

[root@Slave1-ip132 keepalived]$ service realserver start

LVS-DR real server starts successfully.\n

[root@Slave1-ip132 keepalived]$

[root@Slave1-ip132 keepalived]$ ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 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

    inet 192.168.59.136/32 brd 192.168.59.136 scope global lo:0

    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 00:0c:29:f9:c5:77 brd ff:ff:ff:ff:ff:ff

    inet 192.168.59.132/24 brd 192.168.59.255 scope global eth0

    inet6 fe80::20c:29ff:fef9:c577/64 scope link

       valid_lft forever preferred_lft forever

 

此时,虽然2 个节点都启动了 192.168.59.136 ,但是主机是 ping 不通虚拟机的,因为 lo 是回环接口:

C:\Users\chinasoft_lhrxxt>ping 192.168.59.136

 

Pinging 192.168.59.136 with 32 bytes of data:

Request timed out.

Request timed out.

Request timed out.

Request timed out.

 

Ping statistics for 192.168.59.136:

    Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),

 

 

一.6   分别在133 上和 134 上启动 keepalived 进程

/etc/init.d/keepalived start

 

[root@Slave2-ip133 keepalived-2.0.19]$ /etc/init.d/keepalived start

Starting keepalived: [  OK  ]

[root@Slave2-ip133 keepalived-2.0.19]$ ps -ef|grep keep

root     31496     1  0 17:37 ?        00:00:00 keepalived -D

root     31497 31496  0 17:37 ?        00:00:00 keepalived -D

root     31498 31496  0 17:37 ?        00:00:00 keepalived -D

root     31507 21466  0 17:37 pts/0    00:00:00 grep keep

[root@Slave2-ip133 keepalived-2.0.19]$ ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 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 00:0c:29:2b:03:17 brd ff:ff:ff:ff:ff:ff

    inet 192.168.59.133/24 brd 192.168.59.255 scope global eth0

    inet 192.168.59.136/32 scope global eth0

    inet6 fe80::20c:29ff:fe2b:317/64 scope link

       valid_lft forever preferred_lft forever

 

此时就可以ping 通虚拟机了:

C:\Users\chinasoft_lhrxxt>ping 192.168.59.136

 

Pinging 192.168.59.136 with 32 bytes of data:

Reply from 192.168.59.136: bytes=32 time<1ms TTL=64

Reply from 192.168.59.136: bytes=32 time<1ms TTL=64

Reply from 192.168.59.136: bytes=32 time<1ms TTL=64

Reply from 192.168.59.136: bytes=32 time<1ms TTL=64

 

Ping statistics for 192.168.59.136:

    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),

Approximate round trip times in milli-seconds:

    Minimum = 0ms, Maximum = 0ms, Average = 0ms

 

此时查看LVS 集群状态,可以看到集群下有两个 RealServer ,调度算法,权重等信息。 ActiveConn 代表当前 RealServer 的活跃连接数。

[root@Slave2-ip133 keepalived-2.0.19]$ ipvsadm -Ln

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

TCP  192.168.59.136:3332 rr

  -> 192.168.59.131:3332          Route   1      0          0         

  -> 192.168.59.132:3332          Route   1      0          0         

 

 

 

 

一.7   测试高可用

一.7.1   验证LVS 负载均衡转发策略 -- 负载均衡

MySQL 客户端使用 VIP 连接数据库,并查看所连接的数据库服务器 ID 。可以看到,每次执行依次连接到 192.168.59.131 192.168.59.132 MySQL ,证明是轮询策略产生的结果。

mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"

mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"

mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"

mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"

mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"

mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"

C:\Users\chinasoft_lhrxxt>mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"
Warning: Using a password on the command line interface can be insecure.
+---------------+-----------+
| Variable_name | Value     |
+---------------+-----------+
| server_id     | 573332132 |
+---------------+-----------+
 
C:\Users\chinasoft_lhrxxt>mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"
Warning: Using a password on the command line interface can be insecure.
+---------------+-----------+
| Variable_name | Value     |
+---------------+-----------+
| server_id     | 573332131 |
+---------------+-----------+
 
C:\Users\chinasoft_lhrxxt>mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"
Warning: Using a password on the command line interface can be insecure.
+---------------+-----------+
| Variable_name | Value     |
+---------------+-----------+
| server_id     | 573332132 |
+---------------+-----------+
 
C:\Users\chinasoft_lhrxxt>mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"
Warning: Using a password on the command line interface can be insecure.
+---------------+-----------+
| Variable_name | Value     |
+---------------+-----------+
| server_id     | 573332131 |
+---------------+-----------+
 
C:\Users\chinasoft_lhrxxt>mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"
Warning: Using a password on the command line interface can be insecure.
+---------------+-----------+
| Variable_name | Value     |
+---------------+-----------+
| server_id     | 573332132 |
+---------------+-----------+
 
C:\Users\chinasoft_lhrxxt>mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"
Warning: Using a password on the command line interface can be insecure.
+---------------+-----------+
| Variable_name | Value     |
+---------------+-----------+
| server_id     | 573332131 |
+---------------+-----------+

 

 

一.7.2   模拟LVS master 失效

停止133 上的 Keepalived 服务,发现 VIP136 已经漂移到了 134 上:

/etc/init.d/keepalived stop

ip a

此时连接MySQL ,负载均衡不受影响。

mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"

mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"

mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"

mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"

mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"

mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"

此时再次启动133 keepalived 服务,它已经变为 slave ,而且并不会去抢占 master ,这是由 nopreempt 参数决定的。

 

一.7.3   模拟131 宕机

131 上关闭 MySQL 实例:

pkill -9 mysqld

此时,LVS 检测到了 192.168.59.131 上的 MySQL Server 宕机,集群自动剔除了故障节点。此时集群中只有一个 RealServer 的地址,即 192.168.59.132:3332

[root@Slave2-ip133 ~]$ ipvsadm -Ln

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

TCP  192.168.59.136:3332 rr

  -> 192.168.59.132:3332          Route   1      0          0    

此时连接MySQL ,可以看到应用不受影响,但只连接到一台 MySQL 服务器。

mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"
mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"
mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"
mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"
mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"
mysql -uroot -plhr -h192.168.59.136 -P3332 -e "show variables like 'server_id'"

重新启动192.168.59.131 上的 MySQL 后, LVS 自动将故障节点自动加入集群。

[root@Slave2-ip133 ~]$ ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.59.136:3332 rr
  -> 192.168.59.131:3332          Route   1      0          0         
  -> 192.168.59.132:3332          Route   1      0          0

 

一.8   总结

之所以要使用MySQL 双主复制而不是主从复制,是因为本方案中并没有涉及读写分离,而是在两个等价的 MySQL 服务器之间做读写负载均衡。

本例中除了简单配置外,没有任何自定义的脚本。

Keepalived 利用 VRRP 实现了 LVS HA ,避免了 LVS 服务器的单点故障,出现故障时可以自动切换到正常的节点。

LVS 服务器提供了负载均衡的作用,将用户请求分发到多个 RealServer 。同时,一台 RealServer 故障并不会影响整个集群,因为 LVS 会检测 RealServer 的状态,并据此自动添加或删除集群中的 RealServer 服务。

如本例的配置,需要考虑单台MySQL 服务器的负载最好不要超过 50% ,否则一旦某台 MySQL 服务器故障,可能出现另一台正常 MySQL 不堪重负的情况。

 




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


 上一篇我们使用Keepalived的HA功能,实现MySQL主从复制的自动故障切换。它的工作原理是:初始将MySQL的主从两个主机赋予不同的优先级别,当Keepalived启动时,会将VIP绑定到高优先级的主库上。在Keepalived中调用自定义脚本check_run,每分钟检查一次本机MySQL的服务器状态,如果MySQL不可用,则杀掉本机的keepalived进程。Keepalived每秒钟会检查一次本机的keepalived进程,如果进程不存在,则将VIP绑定到另一台机器上,如果这台机器原来是从库,则同时调用master.sh脚本执行从库切换为主库的操作。


        本篇我们将做另一个实验,利用Keepalived的IPVS功能,调用LVS实现MySQL双主复制的读写负载均衡,同时保证负载均衡器和MySQL的高可用性。实验环境如图1所示。



图1


 


一、Keepalived和LVS简介

 


1. Keepalived简介

        参见“使用Keepalived实现MySQL主从高可用”。


2. LVS简介

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


图2



        LVS由ipvs和ipvsadm两部分组成:

ipvs:ipvs是工作在内核空间netfilter的input链上的框架,通过用户空间工具进行管理,其中是真正生效实现调度的代码。

ipvsadm:ipvsadm负责为ipvs内核框架编写规则,是管理配置内核中ipvs程序的用户空间的管理工具。

        LVS是工作在linux内核空间的tcp/ip栈的应用程序,其程序名称为ipvs。ipvs会监听input链上的请求,一旦请求的是集群服务的话,ipvs钩子函数会将请求拉出并进行报文修改,强制转发到postrouting处理,关系如图3所示。


 


图3



        在客户端看来,LVS就是一个真实的应用服务器。客户端向LVS发送请求信息,LVS接收数据报文至内核空间,工作在input链上的ipvs模块会判断用户请求是不是定义的后端服务器,如果用户请求的就是定义的后端集群服务,数据报文传送到input链上时,input链会强行将数据报文转发给postrouting,postrouting将数据报文传送给后端真实服务器。LVS的特点在于超强的分流功能,但它只能负责调度流量的去向,没有办法实现在业务层分流负载。


        LVS可以独立使用,但更普遍的做法是与Keepalived一起使用。LVS提供负载均衡,Keepalived提供健康检查,故障转移,提高系统的可用性。Keepalived中的LVS配置包括虚拟主机组(Virtual Server Group)和虚拟主机(Virtual Server)。这些配置会传递给ipvsadm作为参数。采用这样的架构以后,很容易对现有系统进行扩展,在后端添加或者减少realserver后,只需要更改Keepalived配置文件中的LVS部分即可。


 


 


二、安装配置

        环境:

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


        在本环境中的RealServer就是两台MySQL服务器,LVS和RealServer分别使用两台主机。当LVS架构中的Director Server和RealServer工作在同一台机器上时,需要注意SYN_RECV问题,即会出现两台director无限循环转发请求的情况。对该问题的讨论参见“怎么样让LVS和realserver工作在同一台机器上”。


        在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

        在172.16.1.124和172.16.1.125上用root用户执行以下命令:


 


 


yum -y install ipvsadm

2. 下载安装Keepalived

        在172.16.1.124和172.16.1.125上安装Keepalived,详细步骤参见“使用Keepalived实现MySQL主从高可用”。

 


3. Keepalived配置

        172.16.1.124初始为keepalived的master,其上的keepalived配置文件如下:


[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~]#

        172.16.1.125初始为keepalived的slave,其上的keepalived配置文件如下:


[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~]#

        master与slave的keepalived配置文件中只有priority设置不同,master为100,slave为90,其它全一样。配置文件是以块形式组织的,每个块都在{}包围的范围内,#和!开头的行都是注释。global_defs、vrrp_sync_group、vrrp_instance部分的配置说明参见“使用Keepalived实现MySQL主从高可用”。


        本例中没有配置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的网络配置脚本

        在172.16.1.126和172.16.1.127上建立/etc/init.d/realserver文件,内容如下:


#!/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

        执行下面的命令将该脚本加入开机自启动:


chmod +x /etc/init.d/realserver

echo "/etc/init.d/realserver" >> /etc/rc.d/rc.local

        执行以下命令配置realserver:


service realserver start

        命令执行后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上执行以下命令:

/etc/init.d/keepalived start


2. 查看master和slave上的VIP

        结果分别如图6、7所示,可以看到VIP已经成功绑定到172.16.1.124。

 


图6

图7



        此时查看LVS集群状态,可以看到集群下有两个RealServer,调度算法,权重等信息。ActiveConn代表当前RealServer的活跃连接数。


 


[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~]#

 3. 验证LVS负载均衡转发策略

        MySQL客户端使用VIP连接数据库,并查看所连接的数据库服务器ID。可以看到,每次执行依次连接到172.16.1.126和172.16.1.127的MySQL,证明是轮询策略产生的结果。


 


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   |

+---------------+-------+

4. 模拟LVS的master失效

        停止master上的keepalived服务,在172.16.1.124上执行以下命令:


/etc/init.d/keepalived stop

        再次查看172.16.1.124、172.16.1.125绑定的VIP分别如图8、9所示。可以看到VIP已经漂移到172.16.1.125上,它成为了新的master。


 



图8 


 

图9



        此时连接MySQL,负载均衡不受影响。


 


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   |

+---------------+-------+

        此时再次启动172.16.1.124上keepalived服务,它已经变为slave,而且并不会去抢占master,这是由nopreempt参数决定的。


5. 模拟mysqld crash

        在172.16.1.126上执行以下命令:

pkill -9 mysqld


        此时,LVS检测到了172.16.1.126上的MySQL Server宕机,集群自动剔除了故障节点。此时集群中只有一个RealServer的地址,即172.16.1.127:3306。


 


[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~]#

        此时连接MySQL,可以看到应用不受影响,但只连接到一台MySQL服务器。


 


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   |

+---------------+-------+

        重新启动172.16.1.126上的MySQL后,LVS自动将故障节点自动加入集群。


 


[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~]#

四、总结

之所以要使用MySQL双主复制而不是主从复制,是因为本方案中并没有涉及读写分离,而是在两个等价的MySQL服务器之间做读写负载均衡。

本例中除了简单配置外,没有任何自定义的脚本。

Keepalived利用VRRP实现了LVS的HA,避免了LVS服务器的单点故障,出现故障时可以自动切换到正常的节点。

LVS服务器提供了负载均衡的作用,将用户请求分发到多个RealServer。同时,一台RealServer故障并不会影响整个集群,因为LVS会检测RealServer的状态,并据此自动添加或删除集群中的RealServer服务。

如本例的配置,需要考虑单台MySQL服务器的负载最好不要超过50%,否则一旦某台MySQL服务器故障,可能出现另一台正常MySQL不堪重负的情况。

参考:

MySQL主主复制+LVS+Keepalived实现MySQL高可用性

LVS NAT,DR,TUN三种负载原理

Keepalived权威指南






About Me

........................................................................................................................

● 本文作者:小麦苗,部分内容整理自网络,若有侵权请联系小麦苗删除

● 本文在itpub、博客园、CSDN和个人微 信公众号( xiaomaimiaolhr)上有同步更新

● 本文itpub地址: http://blog.itpub.net/26736162

● 本文博客园地址: http://www.cnblogs.com/lhrbest

● 本文CSDN地址: https://blog.csdn.net/lihuarongaini

● 本文pdf版、个人简介及小麦苗云盘地址: http://blog.itpub.net/26736162/viewspace-1624453/

● 数据库笔试面试题库及解答: http://blog.itpub.net/26736162/viewspace-2134706/

● DBA宝典今日头条号地址: http://www.toutiao.com/c/user/6401772890/#mid=1564638659405826

........................................................................................................................

● QQ群号: 230161599 、618766405

● 微 信群:可加我微 信,我拉大家进群,非诚勿扰

● 联系我请加QQ好友 646634621 ,注明添加缘由

● 于 2020-02-01 06:00 ~ 2020-02-31 24:00 在西安完成

● 最新修改时间:2020-02-01 06:00 ~ 2020-02-31 24:00

● 文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解

● 版权所有,欢迎分享本文,转载请保留出处

........................................................................................................................

小麦苗的微店https://weidian.com/s/793741433?wfr=c&ifr=shopdetail

小麦苗出版的数据库类丛书http://blog.itpub.net/26736162/viewspace-2142121/

小麦苗OCP、OCM、高可用网络班http://blog.itpub.net/26736162/viewspace-2148098/

小麦苗腾讯课堂主页https://lhr.ke.qq.com/

........................................................................................................................

使用 微 信客户端扫描下面的二维码来关注小麦苗的微 信公众号( xiaomaimiaolhr)及QQ群(DBA宝典)、添加小麦苗微 信, 学习最实用的数据库技术。

........................................................................................................................

欢迎与我联系

 

 



来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26736162/viewspace-2676685/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
QQ:646634621| 网名:小麦苗| 微信公众号:xiaomaimiaolhr| 11g OCM| QQ群:618766405 微信群:私聊| 《数据库笔试面试宝典》作者| OCP、OCM、高可用(RAC+DG+OGG)网络班开讲啦,有需要的小伙伴可以私聊我。

注册时间:2012-09-23

  • 博文量
    1428
  • 访问量
    8505181