Keepalived+MySQL实现高可用

一、环境规划

主机名 IP地址 备注
服务器A hosta 192.168.60.101 keepalive主节点、Mysql主节点1
服务器B hostb 192.168.60.102 keepalive备节点、Mysql主节点2
192.168.60.222 keepalive虚拟IP,会在keepalive启动后分配到上面2台机器的主节点上

image-20220723175711858

二、Mysql安装配置

为了简化mysql安装过程,这里使用docker来进行安装配置。

1
2
3
4
docker pull mysql:5.7
mkdir /opt/mysql/conf -p
mkdir /opt/mysql/data -p
vim /opt/mysql/conf/my.cnf

服务器A配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
## my.cnf
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8

[mysqld]
# 设置3306端口
port = 3306
# 设置mysql的安装目录
# basedir=/var/lib/mysql
# 设置 mysql数据库的数据的存放目录,如果是MySQL 8+ 不需要以下配置,系统自己生成即可,否则有可能报错
datadir=/var/lib/mysql/data
# 允许最大连接数
max_connections=20
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# 最大连接数
max_connections=500

server_id = 1 #服务编号(集群中每个节点的服务编号需要唯一)
binlog_format=ROW
log_bin=/var/lib/mysql/binlog
auto-increment-increment = 2 #主键递增的步长【由于数双主,如果是自动递增的主键的话,会出现主键冲突的问题】
auto-increment-offset = 1 #主键自动递增的初始值【双主的起始值设置的时候需要错开】
slave-skip-errors = all #忽略所有复制产生的错误
gtid_mode=ON
enforce-gtid-consistency=ON

服务器B配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
## my.cnf
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8

[mysqld]
# 设置3306端口
port = 3306
# 设置mysql的安装目录
# basedir=/var/lib/mysql
# 设置 mysql数据库的数据的存放目录,如果是MySQL 8+ 不需要以下配置,系统自己生成即可,否则有可能报错
datadir=/var/lib/mysql/data
# 允许最大连接数
max_connections=20
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# 最大连接数
max_connections=500

server_id = 2 #服务编号(集群中每个节点的服务编号需要唯一)
binlog_format=ROW
log_bin=/var/lib/mysql/binlog
auto-increment-increment = 2 #主键递增的步长【由于数双主,如果是自动递增的主键的话,会出现主键冲突的问题】
auto-increment-offset = 2 #主键自动递增的初始值【双主的起始值设置的时候需要错开】
slave-skip-errors = all #忽略所有复制产生的错误
gtid_mode=ON
enforce-gtid-consistency=ON
1
2
3
4
5
6
7
8
9
#运行mysql实例
docker run -d --name mysql -p 3306:3306 -v /opt/mysql/conf:/etc/mysql/conf.d -v /opt/mysql/data:/var/lib/mysql/data -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

#进入mysql容器内
docker exec -it mysql bash

#创建复制用户,2个数据库上都要创建
mysql -uroot -p123456
grant replication slave on *.* to 'rep'@'%' identified by '123';

将服务器A数据库数据导出并导入到数据库B中。在服务器B上进行如下操作:

1
2
mysqldump -uroot -p123456 -h 192.168.60.101 --single-transaction --all-databases --master-data=2  > hosta.sql
mysql -uroot -p123456 < hosta.sql

在服务器B上开启数据库复制

1
mysql -uroot -p123456
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
-- 配置复制
mysql> CHANGE MASTER TO
-> master_host='192.168.60.101',
-> master_port=3306,
-> master_user='rep',
-> master_password='123',
-> MASTER_AUTO_POSITION = 1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

-- 开启复制
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)


-- 查看复制状态
mysql> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.60.101
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000001
Read_Master_Log_Pos: 611
Relay_Log_File: a8bb67ca2607-relay-bin.000011
Relay_Log_Pos: 445
Relay_Master_Log_File: binlog.000001
#下面出现两个Yes就表示连接服务器A成功
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

在服务器A上开启数据库复制

1
mysql -uroot -p123456
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
-- 配置复制
mysql> CHANGE MASTER TO
-> master_host='192.168.60.102',
-> master_port=3306,
-> master_user='rep',
-> master_password='123',
-> MASTER_AUTO_POSITION = 1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

-- 开启复制
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)


-- 查看复制状态
mysql> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.60.102
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000001
Read_Master_Log_Pos: 614
Relay_Log_File: 85921dd2dd0a-relay-bin.000011
Relay_Log_Pos: 445
Relay_Master_Log_File: binlog.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

测试双主复制

1
2
3
4
5
6
7
8
9
--在服务器A上创建数据库
create database testa;
--在服务器B上查看数据库
show databases;

--在服务器B上创建数据库
create database testb;
--在服务器A上查看数据库
show databases;

三、Keepalived安装配置

安装过程以及使用请看《keepalived学习笔记》一文。在本次案例中Keepalived配置如下:

服务器A:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
! Configuration File for keepalived

global_defs {
#通知邮件,当keepalived发生切换时需要发email给具体的邮箱地址
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
#设置发件人的邮箱信息
notification_email_from Alexandre.Cassen@firewall.loc
#指定smpt服务地址
smtp_server 192.168.200.1
#指定smpt服务连接超时时间
smtp_connect_timeout 30
#运行keepalived服务器的一个标识(每个服务的不一样),可以用作发送邮件的主题信息
router_id keepalived1
#默认是不跳过检查。检查收到的VRRP通告中的所有地址可能会比较耗时,设置此命令的意思是,如果通告与接收的上一个通告来自相同的master路由器,则不执行检查(跳过检查)
vrrp_skip_check_adv_addr
#注释掉严格遵守VRRP协议,否则无法正常使用虚拟ip,如ping
#vrrp_strict
#在一个接口发送的两个免费ARP之间的延迟。可以精确到毫秒级。默认是0
vrrp_garp_interval 0
#在一个网卡上每组na消息之间的延迟时间,默认为0
vrrp_gna_interval 0
}

#加入以下vrrp_script
vrrp_script chk_mysql_port {
#执行脚本的位置
script "/etc/keepalived/chk_mysql_port"
#执行脚本的周期,秒为单位
interval 2
#权重的计算方式
weight -20
}

vrrp_instance VI_1 {
#有两个值可选MASTER主 BACKUP备(可以都设置为BACKUP,让keepalived自己根据priority值大小自己选举MASTER)
state MASTER
#vrrp实例绑定的网卡接口名称(可以通过ifconfig命令查看),用于发送VRRP
interface ens33
#指定VRRP实例ID(相同虚拟ip的多个服务该值要相同),范围是0-255
virtual_router_id 51
#指定优先级,优先级高的将成为MASTER
priority 100
#指定发送VRRP通告的间隔,单位是秒
advert_int 1
authentication {
#指定认证方式。PASS简单密码认证(推荐)
auth_type PASS
#指定认证使用的密码,最多8位
auth_pass 1111
}
#虚拟IP地址设置虚拟IP地址(需要和以上网卡接口的真实ip在同一网段),供用户访问使用,可设置多个,一行一个
virtual_ipaddress {
192.168.60.222
}
#加入以下track_script
track_script {
chk_mysql_port
}
}

服务器B:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
! Configuration File for keepalived

global_defs {
#通知邮件,当keepalived发生切换时需要发email给具体的邮箱地址
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
#设置发件人的邮箱信息
notification_email_from Alexandre.Cassen@firewall.loc
#指定smpt服务地址
smtp_server 192.168.200.1
#指定smpt服务连接超时时间
smtp_connect_timeout 30
#运行keepalived服务器的一个标识(每个服务的不一样),可以用作发送邮件的主题信息
router_id keepalived2
#默认是不跳过检查。检查收到的VRRP通告中的所有地址可能会比较耗时,设置此命令的意思是,如果通告与接收的上一个通告来自相同的master路由器,则不执行检查(跳过检查)
vrrp_skip_check_adv_addr
#注释掉严格遵守VRRP协议,否则无法正常使用虚拟ip,如ping
#vrrp_strict
#在一个接口发送的两个免费ARP之间的延迟。可以精确到毫秒级。默认是0
vrrp_garp_interval 0
#在一个网卡上每组na消息之间的延迟时间,默认为0
vrrp_gna_interval 0
}

#加入以下vrrp_script
vrrp_script chk_mysql_port {
#执行脚本的位置
script "/etc/keepalived/chk_mysql_port"
#执行脚本的周期,秒为单位
interval 2
#权重的计算方式
weight -20
}

vrrp_instance VI_1 {
#有两个值可选MASTER主 BACKUP备(可以都设置为BACKUP,让keepalived自己根据priority值大小自己选举MASTER)
state BACKUP
#vrrp实例绑定的网卡接口名称(可以通过ifconfig命令查看),用于发送VRRP
interface ens33
#指定VRRP实例ID(相同虚拟ip的多个服务该值要相同),范围是0-255
virtual_router_id 51
#指定优先级,优先级高的将成为MASTER
priority 90
#指定发送VRRP通告的间隔,单位是秒
advert_int 1
authentication {
#指定认证方式。PASS简单密码认证(推荐)
auth_type PASS
#指定认证使用的密码,最多8位
auth_pass 1111
}
#虚拟IP地址设置虚拟IP地址(需要和以上网卡接口的真实ip在同一网段),供用户访问使用,可设置多个,一行一个
virtual_ipaddress {
192.168.60.222
}
#加入以下track_script
track_script {
chk_mysql_port
}
}
1
vim /etc/keepalived/chk_mysql_port
1
2
3
4
5
#!/bin/bash
counter=$(netstat -na|grep "LISTEN"|grep "3306"|wc -l)
if [ "${counter}" -eq 0 ]; then
killall keepalived
fi

四、测试

在客户端通过虚拟ip:192.168.60.222连接mysql。然后尝试关闭服务器A的mysql看是否客户端还能正常使用(虚拟ip指向服务器B)。

1
2
#在服务器A上关闭mysql
docker stop mysql

参考:

https://www.cnblogs.com/lijiaman/p/13430668.html



----------- 本文结束 -----------




如果你觉得我的文章对你有帮助,你可以打赏我哦~
0%