keepalived实现Mysql的双机热备自动故障切换,看这一篇就够了!

07-03 1091阅读

目录

一、什么是双热备份?

二、什么是Mysql的双热备份? 

三、什么是keepalived?

四、实现Mysql的双机热备

1、配置双主复制参数

2、创建用于复制的MySQL用户

3、将A节点的数据拷贝到B节点

4、B节点上开启复制

五、 安装配置keepalived,完成故障自动切换

1、keepalived的安装

2、keepalived的配置

3、验证keepalived搭建虚拟IP是否成功

4、验证主节点发生故障时,是否能够自动切换 


一、什么是双热备份?

       双热备份(也称为双机热备份)是指通过两台服务器的相互备份,在一台服务器出现故障时,另一台服务器能够自动接管业务,保证系统服务的持续性和高可用性。双热备份的核心也就是是通过两台服务器之间的实时同步和故障检测来实现高可用性。这种备份方式确保当主设备发生故障时,备用设备能迅速接管业务,从而避免服务中断。

二、什么是Mysql的双热备份? 

       MySQL的双热备份通常是指通过主从复制机制实现两台服务器间的实时数据同步,从而确保数据的高可用性和一致性。双热备份在MySQL中主要依赖于其内置的主从复制(Replication)功能。在此架构中,一台服务器作为“主”(Master)服务器,负责处理数据写入和查询操作,而另一台服务器则作为“从”(Slave)服务器,主要用于备份和查询负载平衡。当主服务器发生故障时,从服务器可以迅速接管主服务器的角色,保证服务的持续性。下图是Mysql主从复制原理图:

keepalived实现Mysql的双机热备自动故障切换,看这一篇就够了!        

       从上图可知,Mysql主从复制的大致流程就是:主库在事务提交时,会把数据变更记录在二进制日志文件Binlog中。然后,从库使用IO Thread线程去读取主库的二进制日志文件Binlog ,并写入到从库的中继日志Relay Log。最后,从库读取并解析中继日志中的日志事件,然后在从库上执行相应的数据更新操作,确保从库的数据与主库一致。

三、什么是keepalived?

       Keepalived是一个基于VRRP协议的轻量级的中间件,用于实现高可用性的服务。它可以在多台服务器之间进行状态同步,并提供故障切换的功能,保证服务的连续性和可用性。Keepalived通过VRRP协议进行通信,通过设定一个虚拟IP地址,将多台服务器绑定到同一个IP上。其中一个服务器作为Master角色,负责提供服务;其他服务器则处于Backup角色,作为热备份。当Master服务器发生故障时,Backup服务器会立即接管Master的角色,继续提供服务。

四、实现Mysql的双机热备

       为了确保在主节点宕机的情况下,从节点能够无缝地接管主节点的职责,我们需要为从节点授予与主节点相同的读写权限。这样的设计允许在主节点恢复后,可以将其重新配置为从节点,继续进行数据同步和备份。这种架构实质上也就是MySQL的双主复制模式,这样做的好处就是可以提高系统的高可用性和数据的安全性。当然,这种模式下,从节点无法分担主节点的处理负荷,这可能导致从节点资源的不完全利用。但是,如果我们的首要目标是确保系统的高可用性和服务的持续不间断,并且系统并未面临大量的读写请求压力,那么这种双主复制模式就显得尤为简洁且高效。在这种情况下,其优势在于能够快速适应主节点的故障,同时保持数据的安全和一致性。以下便是实施过程,默认A、B两个服务器上的数据库都已装好。

1、配置双主复制参数

在数据库Mysql的配置文件my.cn中配置如下内容

A服务器:

#开启binlog

server-id= 1

log-bin=mysql-bin

binlog_format=ROW

#双主复制新增如下配置

auto-increment-increment = 2            #字段变化增量值

auto-increment-offset = 1               #初始字段ID为1

slave-skip-errors = all                 #忽略所有复制产生的错误

gtid_mode=ON

enforce-gtid-consistency=ON

B服务器:

 #开启binlog

server-id= 2

log-bin=mysql-bin

binlog_format=ROW

#双主复制新增如下配置

auto-increment-increment = 2            #字段变化增量值

auto-increment-offset = 2               #初始字段ID为1

slave-skip-errors = all                 #忽略所有复制产生的错误

gtid_mode=ON

enforce-gtid-consistency=ON

2、创建用于复制的MySQL用户

A、B两个服务器上的节点都需要创建,以下命令需要登录mysql执行。

grant replication slave on *.* to 'copy'@'%' identified by 'zhuoye_copy';

3、将A节点的数据拷贝到B节点

     通过navicate工具即可。

4、B节点上开启复制

以下脚本在B服务器上执行,并且需要登录mysql执行。

-- 配置复制((以下命令整体复制执行))

 CHANGE MASTER TO

 master_host='100.30.60.35',

 master_port=3306,

 master_user='copy',

 master_password=zhuoye_copy',

 MASTER_AUTO_POSITION = 1;

-- 开启复制

start slave;

-- 查看复制状态

show slave status \G

复制状态结果如下:

mysql> show slave status \G

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 100.30.60.35

                  Master_User: copy

                  Master_Port: 3306

                Connect_Retry: 60                 

              Master_Log_File: mysql-bin.000003  #当前I/O线程正在读取的主服务器二进制日志文件的名称

          Read_Master_Log_Pos: 27317    #当前VO线程正在读取的二进制日志的位置

               Relay_Log_File: node3-relay-bin.000002   #SQL线程当前正在读取和执行的中继日志文件的名称。

                Relay_Log_Pos: 242734740  #在当前的中继日志中,SQL线程已读取和执行的位置。

        Relay_Master_Log_File: mysql-bin.000002

             Slave_IO_Running: Yes    #Yes表示io thread的和主库连接正常并能实施复制工作,No则说明与主库通讯异常

            Slave_SQL_Running: Yes   #YES表示正常,NO表示执行失败

              Replicate_Do_DB: 

          Replicate_Ignore_DB: 

           Replicate_Do_Table: 

       Replicate_Ignore_Table: 

      Replicate_Wild_Do_Table: 

  Replicate_Wild_Ignore_Table: 

                   Last_Errno: 0    #slave的SQL线程读取日志参数的的错误数量和错误消息

                   Last_Error: 

                 Skip_Counter: 0

          Exec_Master_Log_Pos: 242734527

              Relay_Log_Space: 3848626220

              Until_Condition: None

               Until_Log_File: 

                Until_Log_Pos: 0

           Master_SSL_Allowed: No

           Master_SSL_CA_File: 

           Master_SSL_CA_Path: 

              Master_SSL_Cert: 

            Master_SSL_Cipher: 

               Master_SSL_Key: 

        Seconds_Behind_Master: 62570    #如果为0,则表示主从同步不延时,反之同步延时

Master_SSL_Verify_Server_Cert: No

                Last_IO_Errno: 0

                Last_IO_Error: 

               Last_SQL_Errno: 0

               Last_SQL_Error: 

  Replicate_Ignore_Server_Ids: 

             Master_Server_Id: 1

                  Master_UUID: a1314f5a-2d44-11ef-9f35-000c295ce23f

             Master_Info_File: /opt/dtcloud/data/mysql/master.info

                    SQL_Delay: 0     #个非负整数,表示秒数,Slave滞后多少秒于master

          SQL_Remaining_Delay: NULL

      Slave_SQL_Running_State: System lock

           Master_Retry_Count: 86400

                  Master_Bind: 

      Last_IO_Error_Timestamp: 

     Last_SQL_Error_Timestamp: 

               Master_SSL_Crl: 

           Master_SSL_Crlpath: 

           Retrieved_Gtid_Set: a1314f5a-2d44-11ef-9f35-000c295ce23f:1-1262

            Executed_Gtid_Set: 630b58ac-2d4d-11ef-bee2-000c292df71b:1-1275,

a1314f5a-2d44-11ef-9f35-000c295ce23f:1-3:5-1172:1174-1204:1207-1236:1238-1248

                Auto_Position: 1

         Replicate_Rewrite_DB: 

                 Channel_Name: 

           Master_TLS_Version: 

1 row in set (0.00 sec)

以下脚本在A服务器上执行,并且需要登录mysql执行。

-- 配置复制(以下命令整体复制执行)

 CHANGE MASTER TO

 master_host='100.30.60.36',

 master_port=3306,

 master_user='copy',

 master_password='zhuoye_copy',

 MASTER_AUTO_POSITION = 1;

-- 开启复制

start slave;

-- 查看复制状态

show slave status \G

到此双主复制就配置完成,想要验证是否成功。可以对两个节点的数据库的某个表进行修改,看该修改是否可以同步到对方库中,如果同步到则就是搭建成功。  

五、 安装配置keepalived,完成故障自动切换

1、keepalived的安装

 以下是keepalived的安装命令以及常用启停等命令。两台服务器均需要安装。

#安装 

yum install -y keepalived

# 开启keepalived

systemctl start keepalived 或者 service keepalived start 

# 关闭keepalived

systemctl stop keepalived 或者 service keepalived stop 

# 查看keepalived运行状态

systemctl status keepalived 或者 service keepalived status

# 重新启动keepalived

systemctl restart keepalived 或者 service keepalived restart

#设置开机自启动

systemctl enable keepalived

2、keepalived的配置

     keepalived的配置文件为:/etc/keepalived/keepalived.conf。

    A服务器keepalived节点的配置:

   

! Configuration File for keepalived

       

global_defs {

notification_email {

zhuoye@qq.com

}

       

notification_email_from ops@wangshibo.cn

smtp_server 127.0.0.1 

smtp_connect_timeout 30

router_id MASTER-HA

}

       

vrrp_script chk_mysql_port {       #检测mysql服务是否在运行。有很多方式,比如进程,用脚本检测等等

    script "/etc/mysql_check/chk_mysql.sh"   #这里通过脚本监测,目录文件权限要和安装keepalived的用户一致,保证可执行

    interval 2                     #脚本执行间隔,每2s检测一次

#脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5

    weight –5                      

    fall 2                         

#检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间)

    rise 1                         #检测1次成功就算成功。但不修改优先级

}

       

vrrp_instance VI_1 {

    state BACKUP                  #这里所有节点都定义为BACKUP

    interface ens192               #指定虚拟ip的网卡接口,ifconfig查看对外的网卡

    mcast_src_ip 100.30.60.35    #本地IP 

    virtual_router_id 51          #路由器标识,MASTER和BACKUP必须是一致的

#定义优先级,数字越大,优先级越高,在同一个vrrp_instance下,MASTER的优先级必须大于BACKUP的优先级。 

    priority 101        

    advert_int 1

    nopreempt           #不抢占模式         

    authentication {   

        auth_type PASS 

        auth_pass 1111     

    }

    virtual_ipaddress {    

        100.30.60.156            #虚拟IP ,最好是同一网段,不然可能无法访问

    }

      

track_script {               

   chk_mysql_port             

  }

}

     B服务器keepalived节点的配置:

global_defs {

notification_email {

zhuoye@qq.com

}

       

notification_email_from ops@wangshibo.cn

smtp_server 127.0.0.1 

smtp_connect_timeout 30

router_id MASTER-HA

}

       

vrrp_script chk_mysql_port {

    script "/etc/mysql_check/chk_mysql.sh"

    interval 2            

    weight -5                 

    fall 2                 

    rise 1               

}

       

vrrp_instance VI_1 {

    state BACKUP

    interface ens192

    mcast_src_ip 100.30.60.36

    virtual_router_id 51    

    priority 99          

    advert_int 1  

    nopreempt

    authentication {   

        auth_type PASS 

        auth_pass 1111     

    }

    virtual_ipaddress {    

        100.30.60.156 

    }

      

track_script {               

   chk_mysql_port          

}

判断MySQL数据库是否宕机的脚本文件,这里A、B服务器均需要配置,配置目录为/etc/mysql_check/chk_mysql.sh。内容如下:

#!/bin/bash

counter=$(netstat -na|grep "LISTEN"|grep "3306"|wc -l)

if [ "${counter}" -eq 0 ]; then

    systemctl stop keepalived

    exit 2

fi

修改chk_mysql.sh的安全上下文,保证keepalived可以执行该脚本 。

chcon -t keepalived_unconfined_script_exec_t  /etc/mysql_check/chk_mysql.sh

keepalived_unconfined_script_exec_t是SELinux中定义的一个上下文,它允许Keepalived进程在执行脚本时绕过特定的SELinux限制。这种上下文是必要的,因为在某些场景下,Keepalived需要执行额外的脚本,例如chk_mysql.sh,来检查MySQL服务的状态并据此调整负载均衡决策。当SELinux运行在Enforcing(强制)模式时,它会强制执行安全策略,这通常能提高系统的安全性。然而,如果未正确设置keepalived_unconfined_script_exec_t上下文,Keepalived可能无法执行所需的脚本。这种情况下,即使MySQL服务出现故障,Keepalived也无法正确地将流量从故障节点转移,导致虚拟IP(VIP)不会漂移到健康的服务器上。

        因此,为了确保高可用性配置的正确性和有效性,必须确保Keepalived有权限执行这些脚本。这通常涉及使用semanage命令或直接修改文件的SELinux上下文属性,以确保脚本与keepalived_unconfined_script_exec_t上下文关联。这样,即使在SELinux的Enforcing模式下,Keepalived也能顺利地执行脚本,保障了服务的连续性和系统的弹性。

注意:在配置完成后,启动MySQL数据库和keepalive时需要注意特定的启动顺序。首先应启动MySQL,随后再启动keepalive。原因在于keepalive会在启动时检查MySQL的运行状态,以确保其正常运行。如果发现MySQL运行异常,keepalive可能会采取相应措施,包括自动关闭服务,以防止将流量错误地导向可能无法正常服务的MySQL实例。

3、验证keepalived搭建虚拟IP是否成功
  • 在A服务器上执行如下命令:

    ip addr

    结果如下:

    1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

        inet 127.0.0.1/8 scope host lo

           valid_lft forever preferred_lft forever

        inet6 ::1/128 scope host 

           valid_lft forever preferred_lft forever

    2: ens192: mtu 1500 qdisc mq state UP group default qlen 1000

        link/ether 00:0c:29:5c:e2:3f brd ff:ff:ff:ff:ff:ff

        inet 100.30.60.35/24 brd 10.3.6.255 scope global noprefixroute ens192

           valid_lft forever preferred_lft forever

        inet 100.30.60.156/32 scope global ens192      #此时的虚拟ip对应的A服务器,B服务器执行相同的命令则不会有该信息

     

    •  在A和B服务器上执行如下命令:

      mysql -uroot -pzhuoye -h100.30.60.156 -e "select @@hostname"

      都是如下结果:

      mysql: [Warning] Using a password on the command line interface can be insecure.
      +------------+
      | @@hostname |
      +------------+
      | node2      |
      +------------+

       node2便是A服务器的主机名,表明通过VIP访问数据库,访问到的都是服务器A上的数据库实例。

      • 用navicate直接连接虚拟vip 10.3.6.156链接成功,即没问题。
        4、验证主节点发生故障时,是否能够自动切换 
        • 把A服务器的Mysql给停掉后使用如下命令查看keepalived的状态。

           systemctl status keepalived

                此时,正常情况下因为Mysql宕机,keepalived的状态也会变为dead。 

          •   在A和B服务器上执行如下命令:

            mysql -uroot -pzhuoye -h100.30.60.156 -e "select @@hostname"

             都是如下结果:

            mysql: [Warning] Using a password on the command line interface can be insecure.
            +------------+
            | @@hostname |
            +------------+
            | node3      |
            +------------+

                   node3便是B服务器的主机名,表明在A服务器上的MySQL宕机后,keepalived的vip漂浮到了B服务器上的MySQL上。所以,此时通过VIP访问数据库,访问到的都是服务器B上的数据库实例。

            注意:此时如果A服务器上的Mysql恢复正常后,keepalived的vip不会再漂浮回A服务器上的MySQL。除非B服务器上的Mysql宕机后,才会重新漂浮到A服务器的Mysql上面。因为我们设置的是不抢占模式。

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]