Mysql高可用集群-双主双活-myql+keeplived

一、特殊情况

常见案例:当生产环境中,当应用服务使用了mysql-1连接信息,在升级打包过程中或者有高频的数据持续写入【对数据一致性要求比较高的场景】,这种情况下,数据库连接信息基本是固定不变的,而如果数据库mysql-1一旦出现问题,这时必须得人工将应用服务停止掉,再将连接的mysql信息改为mysql-2,再在启动应用服务器,比较繁琐,且中断业务,修复故障时间延长,严重时会造成灾难性的后果。

解决方案

针对这个场景,为了不影响现有业务正常使用情况下,满足负载均衡以及故障转移等特点,即业务系统不需要知道后端服务的数据库的使用状态以及健康状态。
策略:Mysql主从复制功能+keepalived 实现双主双活互备
MySQL双活是指两台MySQL服务器MySQL-1、MySQL-2都为master主节点服务器,同时又是对方的slave从节点,每个数据库都可作为主数据库使用,并将对数据库操作的数据时会同步至另外一台MySQL服务中,MySQL-1和MySQL-2互为主从节点
在这里插入图片描述
说明:Keepalived通过虚拟路由冗余协议(VRRP),创建一个虚拟VIP(MySQL-virtual)并代理MySQL-1,MySQL-2提供数据库服务,实现高可用。在相同集群内发送组播包,master主通过VRRP协议发送组播包,告诉从主的状态。当master停止时,VIP会漂移到到另外一台服务器,完成了MySQL数据库切换。
:当MySQL-virtual实际代理MySQL-1时,MySQL-1服务出现故障后,Keepalived通过自身机制,自动将MySQL-2作为实际代理主服务器,不需要人工干预去修改MySQL配置信息,业务无感知的情况下完成了切换,实现了高可用。

二、实现Keepalived+MySQL高可用

1、实例环境说明

服务器名称IP角色
模拟192.168.0.140IP代理
服务器A192.168.0.146真实IP,主MYSQL数据库
服务器B192.168.0.148真实IP,备MYSQL数据库

2、安装mysql

1.在192.168.0.146、192.168.0.148两台服务器安装MySQL服务
2.修改192.168.0.146服务器/etc/my.cnf配置文件,没有的话可自行创建,配置如下:

[client]
#客户端连接端口
port=3306
#客户端连接sock
socket=/opt/mysql/5.7.36/log/mysql.socka
#客户端编码
default-character-set=utf8

[mysqld]
#mysql服务端口
port=3306
#安装目录
basedir=/opt/mysql/5.7.36/
#数据存放目录
datadir=//opt/mysql/5.7.36/data
#sock文件地址
socket=/opt/mysql/5.7.36/log/mysql.sock
#错误日志存放地址
log-error=/opt/mysql/5.7.36/log/mysql.log
#pid文件地址
pid-file=/opt/mysql/5.7.36/log/mysql.pid

#下面内容为mysq主备时配置,单mysql部署护理下面配置
#server-id 多台服务器时,此表示需要唯一
server-id=1
#主从同步bin-log日志文件名
log-bin=mysql-bin
#主从同步时,需要同步的数据库,多个数据库写多行binlog_do_db配置
binlog_do_db=test_db
#主从同步时,不需要同步的数据库,多个数据库写多行binlog_ignore_db配置
#binlog_ignore_db=mysql
#binlog_ignore_db=information_schema
#binlog_ignore_db=sys
#binlog_ignore_db=performance_schema
#主从同步方式
binlog_format=row
#服务端编码
character-set-server=utf8
!includedir /etc/my.cnf.d

3.修改192.168.0.148服务器/etc/my.cnf配置文件,只有server-id不同,为2配置如下

[client]
#客户端连接端口
port=3306
#客户端连接sock
socket=/opt/mysql/5.7.36/log/mysql.socka
#客户端编码
default-character-set=utf8

[mysqld]
#mysql服务端口
port=3306
#安装目录
basedir=/opt/mysql/5.7.36
#数据存放目录
datadir=/opt/mysql/5.7.36/data
#sock文件地址
socket=/opt/mysql/5.7.36/log/mysql.sock
#错误日志存放地址
log-error=/opt/mysql/5.7.36/log/mysql.log
#pid文件地址
pid-file=/opt/mysql/5.7.36/log/mysql.pid

#下面内容为mysq主备时配置,单mysql部署护理下面配置
#server-id 多台服务器时,此表示需要唯一
server-id=2
#主从同步bin-log日志文件名
log-bin=mysql-bin
#主从同步时,需要同步的数据库,多个数据库写多行binlog_do_db配置
binlog_do_db=test_db
#主从同步时,不需要同步的数据库,多个数据库写多行binlog_ignore_db配置
#binlog_ignore_db=mysql
#binlog_ignore_db=information_schema
#binlog_ignore_db=sys
#binlog_ignore_db=performance_schema
#主从同步方式
binlog_format=row
#服务端编码
character-set-server=utf8
!includedir /etc/my.cnf.d

4.重启192.168.0.146,192.168.0.148的mysql服务

[root@128 mysql5.7]# systemctl stop mysqld
[root@128 mysql5.7]# systemctl start mysqld

3、mysql数据库双主双从配置

1.连接192.168.0.146服务器mysql,并创建主从同步账户slavebak,并查看master状态,记录下file、psition值,配置192.168.0.148的mysql从库时使用

[root@128 ~]# /opt/mysql/5.7.36/bin/mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
......
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> grant replication slave on *.* to slavebak@'%' identified by 'slavebak';
mysql> flush privileges;
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |     1287 | test_db      |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)
mysql>

2.连接192.168.0.148服务器,使用slavebak用户远程登录192.168.0.146的MySQL,测试连接是否正常。

[root@129 ~]# /opt/mysql/bin/mysql -h192.168.0.146 -uslavebak -pslavebak
mysql: [Warning] Using a password on the command line interface can be insecure.
......
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> exit;

3.在192.168.0.148服务器用root连接本服务器mysql,并配置192.168.0.146的主库信息

[root@129 ~]# /opt/mysql/bin/mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
......
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> change master to 
    -> master_host='192.168.0.146',            #146服务器mysql ip
    -> master_port=3306,                         #146服务器mysql端口
    -> master_user='slavebak',                   #146服务器mysql从库同步用户
    -> master_password='slavebak',               #146服务器mysql从库同步用户密码
    -> master_log_file='mysql-bin.000002',       #前面记录的146服务mysql file值
    -> master_log_pos=1287;                      #前面记录的146服务mysql psition值
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> start slave;            #启动从库配置

4.查看192.168.0.148从库配置是否成功Slave_IO_Running、Slave_SQL_Running都为yes则成功

mysql> show slave status;
mysql> show slave status \G;
*************************** 1. row ***************************
            ......
            Slave_IO_Running:  Yes                    #此值为yes配置成功
            Slave_SQL_Running: Yes                    #此值为yes配置i成功
            ......
1 row in set (0.01 sec)

5.在192.168.0.148服务器mysql创建主从同步账户slavebak,查看master状态,记录下file、psition值

mysql> grant replication slave on *.* to slavebak@'%' identified by 'slavebak';
mysql> flush privileges;
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |     848  | test_db      |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)

6.连接192.168.0.146服务器并使用root用户连接本服务器mysql,配置192.168.0.148的主库信息

[root@128 ~]# /opt/mysql/bin/mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
......
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> change master to 
    -> master_host='192.168.0.148',            #148服务器mysql ip
    -> master_port=3306,                         #148服务器mysql端口
    -> master_user='slavebak',                   #148服务器mysql从库同步用户
    -> master_password='slavebak',               #148服务器mysql从库同步用户密码
    -> master_log_file='mysql-bin.000002',       #前面记录的148服务mysql file值
    -> master_log_pos=848;                       #前面记录的148服务mysql psition值
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> start slave;            #启动从库配置

7.查看192.168.0.146从库配置是否成功Slave_IO_Running、Slave_SQL_Running都为yes则成功

mysql> show slave status;
mysql> show slave status \G;
*************************** 1. row ***************************
            ......
            Slave_IO_Running:  Yes                    #此值为yes配置成功
            Slave_SQL_Running: Yes                    #此值为yes配置i成功
            ......
1 row in set (0.01 sec)

到这里,192.168.0.146服务器,192.168.0.148服务器双主双从配置完成。

4、Keepalived服务器A安装部署详细步骤

mysql安装包
版本:mysql-5.7.36-el7-x86_64.tar.gz

下载地址:https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.36-el7-x86_64.tar.gz

keepalived安装包
版本:keepalived-2.2.7.tar.gz

下载地址:https://www.keepalived.org/software/keepalived-2.2.7.tar.gz

步骤3:配置keepalived配置文件

vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {

   router_id LVS_DEVEL

}

vrrp_instance VI_1 {
    state MASTER
    #同一网段中同一组virtual_router_id值相同。不同组virtual_router_id值唯一。
    #如server-1、server-2为一组,virtual_router_id=51
    #server-3、server-4为一组,则virtual_router_id不能为51
     
    
    #interface为查到的本机网卡名称                                                                                   
    interface enp0s3
    virtual_router_id 51
    
    #字数越大,优先级越高,master必须大于backup
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        #该ip为虚拟出来的vip地址

        192.168.0.140
    }
}

#配置virtual_server  ip为上面配置的虚拟vip地址  端口为mysql的端口
virtual_server 192.168.0.140 3306 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    #real_server 该配置为实际物理机ip地址 以及实际物理机mysql端口
    real_server 192.168.0.146 3306 {
        weight 3
        #当该ip 端口连接异常时,执行该脚本
        notify_down /etc/keepalived/restartKeepalived.sh
        TCP_CHECK {
            #实际物理机ip地址
            connect_ip 192.168.0.146
            #实际物理机port端口
            connect_port 3306
            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

        }
    }
}
}

步骤4:补充一个脚本执行文件

cd /etc/keepalived
touch restartKeepalived.sh
vi restartKeepalived.sh
#!/bin/bash
systemctl restart keepalived
chmod 777 restartKeepalived.sh

步骤5:执行启动命令

systemctl start keepalived

步骤6:是否正常启动

ip addr list

5、Keepalived服务器B安装部署详细步骤

mysql安装包
版本:mysql-5.7.36-el7-x86_64.tar.gz

下载地址:https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.36-el7-x86_64.tar.gz

keepalived安装包
版本:keepalived-2.2.7.tar.gz

下载地址:https://www.keepalived.org/software/keepalived-2.2.7.tar.gz

步骤3:配置keepalived配置文件

vi /etc/keepalived/keepalived.conf

内容如下:

! Configuration File for keepalived

global_defs {

   router_id LVS_DEVEL

}

vrrp_instance VI_1 {
    state BACKUP
    #interface为查到的本机网卡名称
    interface enp0s3
    #同一网段中同一组virtual_router_id值相同。不同组virtual_router_id值唯一。
    #如server-1、server-2为一组,virtual_router_id=51
    #server-3、server-4为一组,则virtual_router_id不能为51
    
    virtual_router_id 51
    #字数越大,优先级越高,master必须大于backup
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        #该ip为虚拟出来的vip地址
        192.168.0.140
    }
}

#配置virtual_server  ip为上面配置的虚拟vip地址  端口为mysql的端口
virtual_server 192.168.0.140 3306 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    #real_server 该配置为实际物理机ip地址 以及实际物理机mysql端口
    real_server 192.168.0.148 3306 {
        weight 3
        #当该ip 端口连接异常时,执行该脚本
        notify_down /etc/keepalived/restartKeepalived.sh
        TCP_CHECK {
            #实际物理机ip地址
            connect_ip 192.168.0.148
            #实际物理机port端口
            connect_port 3306
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3

        }
    }
}
}

步骤4:补充一个脚本执行文件

cd /etc/keepalived
touch restartKeepalived.sh
vi restartKeepalived.sh
#!/bin/bash
systemctl restart keepalived
chmod 777 restartKeepalived.sh

步骤5:执行启动命令

systemctl start keepalived

步骤6:是否正常启动
在这里插入图片描述

6、模拟故障演示Keepalived漂移

1、将192.168.1.146、192.168.1.148服务器keepalived加入开机自启,并启动服务

[root@128 keepalived-2.2.7]# systemctl enable keepalived
[root@128 keepalived-2.2.7]# systemctl start keepalived

2、启动后keepalived状态为:active(running)则正常

[root@128 keepalived-2.2.7]# systemctl status keepalived

在这里插入图片描述
3.启动后相当于虚拟出一个vip 192.168.0.140,可使用远程连接工具,连接该服务器,连接进去后使用ifconfig查看该虚拟vip实际上使用的实体服务器是146服务器。
4.将146服务器的keepalived应用停止,再次查看140服务ifconfig,可以看到,140服务器自动将实体机ip漂移到了148服务器上, 在148上面运行hostname -I

[root@128 keepalived-2.2.7]# hostname -I
192.168.0.140 192.168.0.148

如果漂移失败,可能是virtual_router_id在同网段内重复导致。可执行命令查看是否有其他ip使用

[root@128 keepalived-2.2.7]# tcpdump -i 网卡名 vrrp -n |grep virtual_router_id值

例如:

[root@128 keepalived-2.2.7]# tcpdump -i eno16777736 vrrp -n |grep 51

mysql双主双活+keepalived高可用部署并测试完成。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐