当前位置: 首页 > news >正文

MySQL—Keepalived+MySQL双主复制实现MySQL高可用

Keepalived原理:

Keepalived 的原理主要基于虚拟路由冗余协议(VRRP,Virtual Router Redundancy Protocol)、健康检查机制和负载均衡机制,以下为你详细介绍:

  1. VRRP 协议实现高可用:VRRP 是 Keepalived 实现高可用性的核心协议。在一个 VRRP 组中,有多台运行 Keepalived 的服务器,其中一台被选举为主(Master)服务器,其他的作为备(Backup)服务器。
    • 选举机制:通过比较设备的优先级(Priority)来确定 Master 。优先级取值范围是 1 到 254,数值越大优先级越高。默认情况下,优先级最高的设备会成为 Master 。当优先级相同时,IP 地址较大的设备会成为 Master 。Master 服务器承担实际的网络流量转发任务,而 Backup 服务器则处于监听状态。
    • 心跳检测:Master 服务器会定期(默认每隔 1 秒)向 Backup 服务器发送 VRRP 通告报文,以告知 Backup 自己的存活状态。Backup 服务器接收到通告报文后,会重置定时器。如果 Backup 服务器在一定时间(通常是几个通告间隔时间)内没有收到 Master 发送的通告报文,就会认为 Master 服务器出现故障,然后 Backup 服务器中优先级最高的设备会升级为 Master ,接管原来 Master 的工作,继续处理网络流量。
    • 状态切换:当原来的 Master 服务器恢复正常后,它会重新参与选举。如果其优先级高于当前的 Master 服务器,那么它会重新成为 Master ,而原来的 Master 则切换回 Backup 状态。
  2. 健康检查机制:Keepalived 可以对服务器的服务状态进行健康检查,以确保提供服务的服务器是正常运行的。
    • 常见检查方式:包括 TCP 端口检查、HTTP 检查、脚本检查等。例如,对于 Web 服务器,可以通过 HTTP 检查方式,向服务器的 Web 端口发送请求,根据服务器的响应来判断服务器是否正常。如果服务器没有响应或者响应状态码不符合预期,Keepalived 就会认为该服务器出现故障,将其从服务池中移除,不再将流量转发到该服务器。
    • 动态调整:通过健康检查,Keepalived 可以实时监测服务器的状态,并根据服务器的状态动态调整负载均衡的策略,保证服务的可用性和稳定性。
  3. 负载均衡机制(结合 LVS 时):Keepalived 常与 Linux 虚拟服务器(LVS)结合使用,实现负载均衡功能。
    • LVS 原理:LVS 是基于 Linux 内核的一种高性能负载均衡技术,它工作在网络层(OSI 模型的第三层),可以根据不同的调度算法(如轮询、加权轮询、最少连接等)将客户端的请求转发到后端的多个真实服务器上。
    • 协同工作:Keepalived 可以管理 LVS 的配置,监控后端真实服务器的状态。当发现某台真实服务器出现故障时,Keepalived 会自动调整 LVS 的配置,将该服务器从负载均衡的服务器池中移除,避免将请求转发到故障服务器上,从而保证服务的连续性和可用性。

综上所述,Keepalived 通过 VRRP 协议实现高可用性,通过健康检查机制确保服务器的正常运行,通过与 LVS 结合实现负载均衡,为网络服务提供了可靠的保障。

MySQL双主复制原理:

MySQL 主主复制(也称为双主复制)是一种特殊的复制模式,两台 MySQL 服务器都可以作为主服务器,同时接受写入操作,并将各自的更改复制到对方,实现双向的数据同步。其原理主要涉及以下几个关键部分:

  1. 二进制日志(Binary Log):每台 MySQL 服务器都启用二进制日志功能,用于记录所有对数据库进行修改的操作,如 INSERT、UPDATE、DELETE 等。二进制日志以事件的形式存储,包含了操作的具体内容和相关信息。例如,当在主服务器 A 上执行一个 INSERT 语句插入一条新记录时,该操作会被记录到主服务器 A 的二进制日志中。
  2. I/O 线程:在主主复制中,每台服务器都有一个 I/O 线程。当一台服务器(假设为服务器 A)上有数据更改并记录到二进制日志后,另一台服务器(服务器 B)的 I/O 线程会连接到服务器 A,请求读取服务器 A 的二进制日志。I/O 线程将读取到的二进制日志事件记录到本地的中继日志(Relay Log)中。例如,服务器 B 的 I/O 线程会定期检查服务器 A 的二进制日志是否有更新,如果有更新则读取并写入到自己的中继日志中。
  3. 中继日志(Relay Log):中继日志用于存储从主服务器复制过来的二进制日志事件。服务器 B 的 I/O 线程将从服务器 A 读取的二进制日志事件写入中继日志后,由服务器 B 的 SQL 线程来处理这些事件。
  4. SQL 线程:每台服务器的 SQL 线程负责读取中继日志中的事件,并在本地数据库上执行这些事件,从而实现数据的同步。例如,服务器 B 的 SQL 线程读取中继日志中来自服务器 A 的 INSERT 操作事件,并在服务器 B 的数据库中执行相同的 INSERT 操作,插入相同的记录。
  5. 设置唯一标识:为了避免循环复制(即一台服务器将另一台服务器复制过来的数据又复制回去),每台服务器都需要设置一个唯一的服务器 ID(server-id)。在 MySQL 的配置文件(如 my.cnf 或 my.ini)中可以设置 server-id 参数,且每台服务器的 server-id 必须不同。例如,服务器 A 的 server-id 设置为 1,服务器 B 的 server-id 设置为 2。
  6. 双向复制配置:要实现主主复制,需要在两台服务器上分别进行配置。每台服务器都要配置对方为自己的主服务器,指定对方的 IP 地址、端口、用户名、密码等连接信息。例如,在服务器 A 上配置服务器 B 为其主服务器,在服务器 B 上配置服务器 A 为其主服务器。

一、环境准备

操作系统

主机

描述

安装服务

Centos 7.9

A

MySQL主机

MySQL、Keepalived

Centos 7.9

B

MySQL主机

MySQL、Keepalived

二、MySQL主主复制部署

注意事项:

在做主主同步前,需要特别注意的一个问题:

主主复制和主从复制有一些区别,因为多主中都可以对服务器有写权限,所以设计到自增长重复问题,例如:

出现的问题(多主自增长ID重复)

1)首先在A和B两个库上创建test表结构;

2)停掉A,在B上对数据表test(存在自增长属性的ID字段)执行插入操作,返回插入ID为1;

3)然后停掉B,在A上对数据表test(存在自增长属性的ID字段)执行插入操作,返回的插入ID也是1;

4)然后 同时启动A,B,就会出现主键ID重复

解决方法:

只要保证两台服务器上的数据库里插入的自增长数据不同就可以了

如:A插入奇数ID,B插入偶数ID,当然如果服务器多的话,还可以自定义算法,只要不同就可以了

在下面例子中,在两台主主服务器上加入参数,以实现奇偶插入!

记住:在做主主同步时需要设置自增长的两个相关配置,如下:

auto_increment_offset 表示自增长字段从那个数开始,取值范围是1 .. 65535。这个就是序号。如果有n台mysql机器,则从第一台开始分为设1,2...n

auto_increment_increment 表示自增长字段每次递增的量,其默认值是1,取值范围是1 .. 65535。如果有n台mysql机器,这个值就设置为n。

在主主同步配置时,需要将两台服务器的:

auto_increment_increment 增长量都配置为2

auto_increment_offset 分别配置为1和2。这是序号,第一台从1开始,第二台就是2,以此类推.....

这样才可以避免两台服务器同时做更新时自增长字段的值之间发生冲突。(针对的是有自增长属性的字段)。

1、在A、B节点上安装mysql服务

#步骤一:解压
mkdir -p /opt/sumscope
cd /opt/sumscope
tar -zxvf  mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz
mv mysql-5.7.44-linux-glibc2.12-x86_64 mysql


#步骤二:在/opt/sumscope/mysql目录下创建data logs目录
cd /opt/sumscope/mysql 
mkdir data logs


#步骤三:初始化MySQL
cd /opt/sumscope/mysql/bin
./mysqld --defaults-file=/opt/sumscope/mysql/my.cnf --basedir=/opt/sumscope/mysql --datadir=/opt/sumscope/mysql/data --user=root --initialize


#步骤四:自定义启动命令
vim /opt/sumscope/mysql/support-files/mysql.server
basedir=/opt/sumscope/mysql
datadir=/opt/sumscope/mysql/data


#步骤五:将启动脚本放在/etc/init.d目录下
cp /opt/sumscope/mysql/support-files/mysql.server /etc/init.d/mysql


#步骤六:创建mysql用户
useradd mysql 
chown -R mysql.mysql /opt/sumscope/mysql/


#步骤七:启动MySQL,修改root用户密码

service mysql start 

cat /opt/sumscope/mysql/logs/mysql_error.log

##修改root用户的密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'ppp';

##使用utf-8编码创建数据库tbook
create database tbook character set utf8 collate utf8_bin;

##授权stc用户远程登录tbook数据库 

grant all privileges on tbook.* to stc@'%' identified by 'ppp';

2、在节点A上进行相关配置

2.1、修改MySQL的配置

#步骤一:修改mysql的配置
root@master ~]# vim /etc/my.cnf
[mysqld]
bind-address=0.0.0.0
port=3306
user=mysql
basedir=/usr/local/mysql
datadir=/data/mysql
#socket=/tmp/mysql.sock
log-error=/data/mysql/mysql.err
pid-file=/data/mysql/mysql.pid
socket=/var/lib/mysql/mysql.sock

#log-bin=master1

server-id = 1        
log-bin = mysql-bin  
binlog-ignore-db = mysql,information_schema
sync_binlog = 1
binlog_checksum = none
binlog_format = mixed
auto-increment-increment = 2    
auto-increment-offset = 1   
slave-skip-errors = all 

#步骤二:重启MySQL服务
[root@master ~]# service mysql restart

2.2、数据同步授权

MySQL [(none)]> grant replication slave,replication client on *.* to root@'192.168.179.131' identified by "ppp";

MySQL [(none)]> flush privileges;
MySQL [(none)]> FLUSH TABLES WITH READ LOCK;

MySQL [(none)]> show master status;
+------------------+----------+--------------+--------------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB         | Executed_Gtid_Set |
+------------------+----------+--------------+--------------------------+-------------------+
| mysql-bin.000002 |     3514 |              | mysql,information_schema |                   |
+------------------+----------+--------------+--------------------------+-------------------+

2.3、创建同步用户sync

CREATE USER 'sync'@'%' identified by '123456';

GRANT REPLICATION SLAVE ON *.*  TO  'sync'@'%';

3、在节点B上进行相关配置

3.1、修改MySQL的配置

root@master ~]# vim /etc/my.cnf
[mysqld]
bind-address=0.0.0.0
port=3306
user=mysql
basedir=/usr/local/mysql
datadir=/data/mysql
#socket=/tmp/mysql.sock
socket=/var/lib/mysql/mysql.sock
log-error=/data/mysql/mysql.err
pid-file=/data/mysql/mysql.pid


server-id = 2       
log-bin = mysql-bin  
binlog-ignore-db = mysql,information_schema
sync_binlog = 1
binlog_checksum = none
binlog_format = mixed
auto-increment-increment = 2    
auto-increment-offset = 2   
slave-skip-errors = all

3.2、数据库同步授权

数据同步授权(iptables防火墙开启3306端口,要确保对方机器能使用下面权限连接到本机mysql)同理slave也要授权给master机器远程同步数据的权限。

MySQL [(none)]> grant replication slave,replication client on *.* to root@'192.168.179.129' identified by "ppp";

MySQL [(none)]> flush privileges;
MySQL [(none)]> FLUSH TABLES WITH READ LOCK;

MySQL [(none)]> show master status;
+------------------+----------+--------------+--------------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB         | Executed_Gtid_Set |
+------------------+----------+--------------+--------------------------+-------------------+
| mysql-bin.000009 |     1945 |              | mysql,information_schema |                   |
+------------------+----------+--------------+--------------------------+-------------------+

3.3、执行主主同步操作

先在slave数据库上做同步master的设置。(确保slave上要同步的数据,提前在master上存在。最好双方数据保持一致)

MySQL [(none)]> unlock tables;


MySQL [(none)]> stop slave;


MySQL [(none)]> change master to master_host='192.168.179.129',master_user='root',master_password='ppp',master_log_file='mysql-bin.000002',master_log_pos=3514;


MySQL [(none)]> start slave;

MySQL [(none)]> show slave status \G;

4、在节点A上执行同步操作

MySQL [(none)]> unlock tables;

MySQL [(none)]> stop slave;

MySQL [(none)]> change master to master_host='192.168.179.131',master_user='root',master_password='ppp',master_log_file='mysql-bin.000009',master_log_pos=1945;

MySQL [(none)]> start slave;

MySQL [(none)]> show slave status \G;

5、测试MySQL主主同步的效果

5.1、在A、B节点上写入数据查看数据同步效果

在节点A上写入数据

5在节点B上查看数据并进行读写操作

 

5.2、测试结论

在上述测试操作后可知节点A写入的数据能被节点B进行增删改操作,节点B写入的数据也能被节点A进行增删改操作,两个MySQL数据库实现了双主复制。

三、安装Keepalived服务

1、在节点A上安装Keepalived作为master节点

#步骤一:安装编译需要的软件包
[root@master ~]# yum install -y pcre-devel openssl-devel popt-devel  #安装依赖包

#步骤二:安装keepalived服务
[root@master ~]# tar zxvf keepalived-1.2.7.tar.gz
[root@master ~]# cd keepalived-1.2.7
[root@master ~]# ./configure --prefix=/usr/local/keepalived
[root@master ~]# make && make install

#将keepalived配置成系统服务
[root@master ~]# cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
[root@master ~]# cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
[root@master ~]# mkdir /etc/keepalived/
[root@master ~]# cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
[root@master ~]# cp /usr/local/keepalived/sbin/keepalived /usr/sbin/


#步骤三:配置keepalived配置文件
########################################################配置文件###############################################
[root@master ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   router_id keep1;                                         #keep1是本节点的标识,一般为hostname
   script_user root                                         #使用root执行            
   enable_script_security
}

vrrp_script check_mysql {
    script "/etc/keepalived/check_mysql.sh"
                 #检测MySQL状态的脚本路径
    interval 2                                              #检测间隔时间
    weight -20                                              #如果如果上述条件成立权重-20
    fall 2                                                  #检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间)
    rise 1                                                  #检测1次成功就算成功。但不修改优先级
}
vrrp_instance VI_1 {
    state MASTER                                            #主节点为MASTER,从节点为BACKUP
    interface ens33                                         #本机网卡名称
    virtual_router_id 100                                   #虚拟路由的ID号,两个节点设置的参数必须一样,相同的VRID为一组,它将决定多播的地址。
    mcast_src_ip 192.168.179.131                            #本机的IP地址
    priority 100                                            #节点的优先级(0~254之间),MASTER比BACKUP高
    nopreempt                                               #优先级设置,异常恢复后再次抢占的问题。
    advert_int 1                                            #组播信息发送间隔,两个的参数必须一样,默认为1s。
    authentication {
      auth_type PASS
      auth_pass p                                           #按照实际生产的需求来(一般为root密码)
    }
    track_script {
      check_mysql
    }
    virtual_ipaddress {
      192.168.179.88                                        #虚拟IP地址,两台主机的必须一致。
   }
}
########################################################配置文件###############################################


#步骤四:配置keepalived检测脚本内容
########################################################MySQL检测脚本内容###############################################
[root@master ~]# vim /etc/keepalived/check_mysql.sh    #检测MySQL服务断开就杀掉keepalived进程,使VIP漂移
 #!/bin/bash                     
 counter=$(netstat -na|grep "LISTEN"|grep ":3306 "|wc -l)
 if [ "${counter}" -eq 0 ]; then
      service keepalived stop
 fi
 ########################################################MySQL检测脚本内容###############################################
 
 #步骤五:对检测脚本添加执行权限、启动keepalived服务
 [root@master ~]# chmod +x /etc/keepalived/check_mysql.sh
 [root@master ~]# /etc/init.d/keepalived start

2、在节点B上安装Keepalived作为slave节点

安装步骤与节点A上安装的方法相同,但是配置文件需要修改

#步骤一:配置keepalived配置文件
########################################################配置文件###############################################
[root@slave ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   router_id keep2;
   script_user root
   enable_script_security
}

vrrp_script check_mysql { 
    script "/etc/keepalived/check_mysql.sh"     #检测脚本所在的位置
    interval 2
    weight -20
    fall 2
    rise 1
}
vrrp_instance VI_1 {
    state BACKUP                        #修改状态名称
    interface ens33                     #修改网卡名称
    virtual_router_id 100
    mcast_src_ip 192.168.179.133        #自己的IP地址
    priority 80                         #作为备节点权重要比主节点小
    advert_int 1
    authentication {
      auth_type PASS
      auth_pass p
    }
    track_script {
      check_mysql                       
    }
    virtual_ipaddress {
      192.168.179.88                   #虚拟IP地址
   }
}
########################################################配置文件###############################################


#步骤二:配置keepalived检测脚本内容用于检测MySQL的状态
########################################################MySQL检测脚本内容###############################################
[root@master ~]# vim /etc/keepalived/check_mysql.sh    #检测MySQL服务断开就杀掉keepalived进程,使VIP漂移
 #!/bin/bash                     
 counter=$(netstat -na|grep "LISTEN"|grep ":3306 "|wc -l)
 if [ "${counter}" -eq 0 ]; then
       service keepalived stop
 fi
 ########################################################MySQL检测脚本内容###############################################
 
 #步骤三:对检测脚本添加执行权限、启动keepalived服务
 [root@master ~]# chmod +x /etc/keepalived/check_mysql.sh
 [root@master ~]# /etc/init.d/keepalived start   

注意:因为keepalived中配置了MySQL状态检测脚本,keepalived在启动时会执行检测脚本,所以等MySQL服务启动成功后再启动keepalived服务,否则服务将无法启动keepalived。

四、高可用场景测试

模拟场景一:当主机MySQL出现故障(3306端口不存在)

步骤一:分别在主机和备机上添加对虚拟IP的验证方式

步骤二:关闭节点A上的MySQL服务

因为配置了权重原因虚拟IP在节点A上,关闭MySQL服务看keepalived服务是否会运行mysql状态检测脚本的内容从而使虚拟IP漂移到节点B上。

步骤三:验证虚拟IP是否漂移到节点B上

在浏览器上验证:输入:http://192.168.179.88/a.html

结论:虚拟IP从主节点漂移到从节点上

步骤四:模拟故障恢复虚拟IP自动迁回

 在浏览器上验证:输入:http://192.168.179.88/a.html

结论:因为主机故障恢复,主节点上的keepalived配置的权重要比从节点的权重要高,所以虚拟IP自动从从节点漂移到从主点上 

相关文章:

  • 基于Rook的Ceph云原生存储部署与实践指南(上)
  • 第九章:多模态大语言模型
  • NL2SQL的应用-长上下文模型在处理NL2SQL任务时,相较于传统模型,有哪些显著的优势
  • CSS 日常开发常用属性总结
  • 数据结构:Top-K问题详解
  • AIGC和搜索引擎的异同
  • 在VSCode中使用MarsCode AI最新版本详解
  • drupal的导入的item-list在哪里查看
  • Java 面试题 20250227
  • 工业AR眼镜的‘芯’动力:FPC让制造更智能【新立电子】
  • PMP项目管理—整合管理篇—4.管理项目知识
  • P8772 [蓝桥杯 2022 省 A] 求和
  • Windows下安装redis-6.2版本及步骤
  • 为什么@Autowired 在属性上被警告,在 setter 方法上不被警告
  • Vue nextTick原理回顾
  • 第四届工程管理与信息科学国际学术会议 (EMIS 2025)
  • Node.js, Bun, Deno 比较概述
  • Nginx 报错:413 Request Entity Too Large
  • DeepSeek在昇腾上的模型部署 - 常见问题及解决方案
  • 本地svn
  • 一周人物|收藏家瓦尔特捐出藏品,女性艺术家“对话”摄影
  • 《缶翁的世界》首发:看吴昌硕等湖州籍书画家的影响
  • 中科院合肥物质院迎来新一届领导班子:刘建国继续担任院长
  • 山东发布高温橙警:预计19日至21日局地可达40℃
  • 媒体评教师拎起学生威胁要扔下三楼:师风师德不能“悬空”
  • 持续降雨存在落石风险,贵州黄果树景区水帘洞将封闭至6月初