lvs+keepalived+mysql双主复制实现负载分担及高可用
Keepalived+lvs+mysql主主复制是比较常用的一种Mysql高可用方案,其中lvs 提供读负载均衡,Keepalived通过虚拟vip漂移实现故障自动转移,而Mysql虽然配置成主主复制,但是一般都是采用单点写入来保证数据一致性。
主机 | IP | 功能 |
---|---|---|
VIP | 192.168.30.250 | |
keep-master | 192.168.30.243 | lvs+keepalived(主) |
keep-slave | 192.168.30.244 | lvs+keepalived(备) |
master-master | 192.168.30.245 | mysql(主) |
master-slave | 1929.168.30.246 | mysql(主) |
mysql双主
mysql双主与主从配置差不多,不过加了下面的几个步骤
[root@mysql-master ~]# vim /etc/my.cnf
[mysqld]
basedir = /usr/local/mysql
datadir = /opt/data
socket = /tmp/mysql.sock
port = 3306
pid-file = /opt/data/mysql.pid
user = mysql
skip-name-resolve
log_slave_updates = 1 ##双主需要开启log_slave_updates功能
server-id = 10 ##不能相同
log-bin = mysql_bin ##双主两个都是log-bin
auto_increment_offset = 1 ##表示自增长字段从1开始,他的取值范围是1 .. 65535
auto_increment_increment = 2 ##表示自增长字段每次递增2,取值范围是2 .. 65535
重启服务
在master主机上创建授权账户,允许slave(192.168.30.246)主机上连接
mysql> grant replication slave on *.* to 'repl'@'192.168.30.246' identified by 'repl';
Query OK, 0 rows affected, 1 warning (0.00 sec)
查看master的当前binlog状态信息
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql_bin.000001 | 455 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
在slave服务器上将master设为自己的主服务器并且开启slave功能
mysql> change master to
-> master_host = '192.168.30.245',
-> master_user = 'repl',
-> master_password = 'repl',
-> master_log_file = 'mysql_bin.000001',
-> master_log_pos = 455 ;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
修改从库配置文件
[root@mysql-slave ~]# cat /etc/my.cnf
[mysqld]
basedir = /usr/local/mysql
datadir = /opt/data
socket = /tmp/mysql.sock
port = 3306
pid-file = /opt/data/mysql.pid
user = mysql
skip-name-resolve
log_slave_updates = 1 ##双主需要开启log_slave_updates功能
server-id = 20 ##不能相同
log-bin = mysql_bin ##双主两个都是log-bin
auto_increment_offset = 1 ##表示自增长字段从1开始,他的取值范围是1 .. 65535
auto_increment_increment = 2 ##表示自增长字段每次递增2,取值范围是2 .. 65535
在slave主机上创建授权账户,允许master(192.168.30.246)主机上连接
mysql> grant replication slave on *.* to 'repl'@'192.168.30.245' identified by 'repl';
Query OK, 0 rows affected, 1 warning (0.00 sec)
查看slave的当前binlog状态信息
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql_bin.000001 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
在master服务器上将slave设为自己的主服务器并且开启slave功能
mysql> change master to
-> master_host = '192.168.30.246',
-> master_user = 'repl',
-> master_password = 'repl',
-> master_log_file = 'mysql_bin.000001',
-> master_log_pos = 154 ;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
keepalived
我这里就用yum安装
主keepalived
[root@keep-master ~]# yum -y install keepalived ipvsadm
[root@keep-master ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id lb01
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 20
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass zyy
}
virtual_ipaddress {
192.168.30.250 ##VIP
}
}
virtual_server 192.168.30.250 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 192.168.30.245 3306 {
weight 1
TCP_CHECK {
connect_port 3306
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.30.246 3306 {
weight 1
TCP_CHECK {
connect_port 3306
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
从库上一样,优先级改一下,设置不抢占就行
[root@keep-slave ~]# yum -y install keepalived ipvsadm
[root@keep-slave ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id lb02
}
vrrp_instance VI_1 {
state BACKUP ##BACKUP
interface ens33
virtual_router_id 20
priority 80 ##优先级要比master小
nopreempt
advert_int 1
authentication {
auth_type PASS
auth_pass zyy
}
virtual_ipaddress {
192.168.30.250
}
}
virtual_server 192.168.30.250 3306 {
delay_loop 3
lb_algo rr
lb_kind DR
# persistence_timeout 5
protocol TCP
real_server 192.168.30.245 3306 {
weight 1
TCP_CHECK {
connect_port 3306
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.30.246 3306 {
weight 1
TCP_CHECK {
connect_port 3306
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
开启keepalived服务
[root@keep-master ~]# systemctl start keepalived
[root@keep-slave ~]# systemctl start keepalived
查看VIP
此时查看LVS集群状态,可以看到集群下有两个RealServer,调度算法,权重等信息。ActiveConn代表当前RealServer的活跃连接数。
[root@keep-master ~]# 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.30.250:3306 rr
-> 192.168.30.245:3306 Route 1 0 0
-> 192.168.30.246:3306 Route 1 0 0
编写RealServer的网络配置脚本
192.168.30.245和192.168.30.246写的东西都是一样的,这里就演示一个
[root@mysql-master ~]# cat /etc/init.d/realserver
#!/bin/bash
VIP=192.168.30.250
. /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
[root@mysql-master ~]# chmod 755 realserver
[root@mysql-master ~]# service realserver start
[root@mysql-slave ~]# chmod 755 realserver
[root@mysql-slave ~]# service realserver start
设置为开机自启
echo "/etc/init.d/realserver" >> /etc/rc.d/rc.local
测试
添加一个测试用户
mysql> grant all on *.* to 'zyy'@'%' identified by 'zyy' ;
Query OK, 0 rows affected, 1 warning (0.00 sec)
1.验证LVS负载均衡转发策略
MySQL客户端使用VIP连接数据库,并查看所连接的数据库服务器ID。可以看到,每次执行依次连接到192.168.30.246和192.168.30.245的MySQL,证明是轮询策略产生的结果。
2.模拟lvs的master故障
停掉master端的keepalived
[root@keep-master ~]# systemctl stop keepalived
可以看到VIP已经漂移
此时连接MySQL,负载均衡不受影响。
3. 模拟其中一方数据库挂了
关闭slave的数据库
[root@mysql-slave ~]# service mysqld stop
Shutting down MySQL............ SUCCESS!
[root@mysql-slave ~]# ss -anlt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 128 :::22 :::*
此时,只有mysql-master端数据库在工作,但可以保证业务的不中断