MySQL共享存储主备模式利用Keepalived实现双机高可用

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

简单介绍

    先简单说下MySQL主从复制与keepalived模式和MySQL共享存储与Keepalived模式

    MySQL共享存储主备模式不同于MySQL主主复制模式,MySQL主主是利用MySQL自带的replication复制技术实现两台或多台MySQL服务器之间互为拉取二进制日志,处于BACKUP的服务器从MASTER获取二进制日志,并将日志解析成相应的SQL语句,然后在从服务器上重新执行一遍主服务器的操作,从而保证主从数据的一致性。MySQL的复制是实时的异步复制过程,能够保持多台数据库之间数据的一致性,利用MySQL复制可以实现多种方式的主从复制备份,如一主一从、一主多从、双主、双主多从,其优点是显而易见的,因此现实环境中不少的企业都使用MySQL复制技术与keepalived、heartbeat、MySQL Proxy、实现MySQL的高可用集群架构。


    当然,MySQL复制技术并非百分百能够保证数据的完成一致性,同时由于开启了二进制日志功能,多少会增加一点I/O,因此在性能上会有一定损耗。简单的主主复制与keepalived模式,在正常情况下两台机器同时提供服务,并且只允许其中一台对外提供写入功能,另外一台提供读功能或只作为备机,当主down之后立即替换为主保证来服务的稳定不中断运行。(当然如果配置auto_increment_offset和auto_incremen_increment参数,可以解决主主同步写入问题)当主故障发生后,keepalived检测到之后将服务切换到从服务器上,在这个过程当中可以看到,keepalived的切换时间是非常迅速的,但此时必须及时修复故障的服务器并继续加入到主从列表中才能保证服务的相对稳定性。一旦有数据异常造成主从不同步都会影响故障的修复效率。


    结合MySQL系统架构的灵活性,那么我在这里简单写一篇关于《MySQL共享存储主备模式利用Keepalived实现双机高可用》的教程,以供大家参考。


    本篇的MySQL共享存储与keepalived的实现方式类似于DRBD+heartbeat模式。DRBD是一个基于软件实现的服务器存储镜像块设备复制的方案,用于实现实时的、透明的数据同步。可以提供大多数HA系统双机热备的方案。由于DRBD是基于软件的,那么其磁盘的性能必然不如物理磁盘。而共享存储在实际环境中是使用比较多的存储方案,一般是由磁盘阵列提供。如SAN、NAS存储。因此由共享存储提供的HA服务有很多,比如,WEB服务器使磁阵替代NFS存储;MySQL HA的共享存储;Oracle RAC的ASM的共享存储。MySQL HA使用共享存储与keepalived的模式并不能两台MySQL都同时提供服务,正常情况下,只有一台提供服务,另外一台完成处于备用的角色,结合keepalived灵活的脚本检测功能,当主服务器down机时,keepalived可以完成做到自动切换,保障服务的稳定运行。那么这种情况下更适用于对业务要求高稳定性的场景中。


    Keepalived的脚本检测功能相当灵活,并且也相对简单。Keepalived的主备角色选举策略由state的状态决定,例如主节点配置为MASTER,备节点配置为BACKUP时,当启动keepalived集群时,处于MASTER状态的节点接管VIP和MySQL服务,而BACKUP状态的节点就处于备用的节点,只有集群发生异常时,keepalived才会根据priority值重新选举MASTER和BACKUP角色,priority值大的节点成为MASTER。在这个角色切换的过程中,如果定义了检测脚本,并且设置了脚本的weight值,当集群异常时,keepalived选举MASTER角色由priority值和weight值之和决定,因此,此时priority+weight就是新的priority值,priority值大的节点被选举为MASTER节点,并且接管集群当中的MySQL服务。


    图为MySQL HA与Keepalived实现高可用的模型

wKiom1iEdH2ipj-DAABAknzJsEQ487.jpg


    那么在这个HA环境中,要注意的一个问题是,正常情况下只有MASTER角色的节点提供MySQL服务,并且也只有MASTER角色的节点挂载共享存储。在keepalived启动时,keepalived会检测各个节点的MySQL服务,只有检测到是正常状态,才被加入到keepalived集群当中(选举为MASTER和BACKUP),如果检测到异常,如MySQL并未启动,此时keepalived并不会把这个节点选举为BACKUP节点,而是被标识为FAULT状态,而当为FAULT状态时,如果MASTER节点down机时,keepalived并不会进行切换,那么此时糟糕的事情是,主备就都不能用了。为了解决这一个问题,应该在检测脚本中自定义为自己想要的状态。如在脚本中定义检测MySQL时,当这台服务器上没有挂载存储,没有VIP,也没有运行MySQL,同时满足这三个条件时,这个节点应该也被视为正常的节点,即BACKUP节点。当MASTER节点down时,才会将服务转移至BACKUP节点当中。定义了灵活的脚本之后,keepalived才能为HA服务提供高可用性。


实验环境

主机
IP
系统
角色
Server1
192.168.6.174
CentOS6.8
MASTER
Server2
192.168.6.175
CentOS6.8
BACKUP
VIP
192.168.6.176


共享存储
/dev/sdb1



实验步骤

一、MySQL安装配置

    Server1和Server2安装MySQL,安装版本保持一致,包括MySQL用户UID、安装目录、数据文件目录都要完成相同。

1
2
3
4
5
6
7
8
9
[root@Server1 ~] # id mysql
uid=498(mysql) gid=500(mysql)  groups =500(mysql)
[root@Server1 ~] # ls /usr/local/mysql/
bin  COPYING  data  docs  include  lib   man   mysql- test   README  scripts  share  sql-bench  support-files
  
[root@Server2 ~] # id mysql
uid=498(mysql) gid=500(mysql)  groups =500(mysql)
[root@Server2 ~] # ls /usr/local/mysql/
bin  COPYING  data  docs  include  lib   man   mysql- test   README  scripts  share  sql-bench  support-files

    只需在主节点执行安装系统数据库的脚本$basedir/scripts/mysql_install_db

1
2
3
[root@Server1 ~] # mount /dev/sdb1 /data/
[root@Server1 ~] # cd /usr/local/mysql/scripts/
[root@Server1 scripts] # ./mysql_install_db --user=mysql --data=/data/mysql/mysql --basedir=/usr/local/mysql --no-defaults


二、Keepalived安装和配置

1、安装keepalived (Server1和Server2节点)

1
2
3
4
[root@Server1 ~] # yum install pcre-devel openssl-devel popt-devel libnl-devel libnfnetlink libnfnetlink-devel
[root@Server1 keepalived-1.3.2] # ./configure --prefix=/usr/local/keepalived --sysconf=/etc --with-kernel-dir=/usr/src/kernels/2.6.32-642.el6.x86_64
[root@Server1 keepalived-1.3.2] # make && make install
[root@Server1 keepalived-1.3.2] # ln -s /usr/local/keepalived/sbin/keepalived /usr/sbin/


2、配置keepalived.conf

    Server1节点(MASTER)

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
! Configuration File  for  keepalived
  
global_defs {
    notification_email {
      mail@huangming.org
    }
    notification_email_from Alexandre.Cassen@firewall.loc
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
    router_id MySQL_HA_DEVEL
    vrrp_skip_check_adv_addr
}
  
vrrp_sync_group MySQL_HA_G1 {
     group {
         MySQL_HA_1
     }
}
  
vrrp_script chk_mysql {
     script  "/etc/keepalived/scripts/check_mysql.sh"
     interval 6
     fall 2
     rise 1
     weight 20
}
  
vrrp_script chage_status {
     script  "/etc/keepalived/scripts/chage_status.sh"
     interval 20
}
  
vrrp_instance MySQL_HA_1 {
     state BACKUP
     interface eth1
     virtual_router_id 176
     priority 100
     advert_int 2
     nopreempt
     authentication {
         auth_type PASS
         auth_pass v262aR1dqH5jTykUbwTo
     }
  
     virtual_ipaddress {
         192.168.6.176 /24  dev eth1
     }
  
     track_script {
         chk_mysql
         chage_status
     }
  
     track_interface {
         eth1
     }
     notify_master  "/etc/keepalived/scripts/notify.sh master"
     notify_backup  "/etc/keepalived/scripts/notify.sh backup"
     notify_fault   "/etc/keepalived/scripts/notify.sh fault"
     notify_stop    "/etc/keepalived/scripts/notify.sh stop"
}


    Server2节点(BACKUP)

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
! Configuration File  for  keepalived
  
global_defs {
    notification_email {
      mail@huangming.org
    }
    notification_email_from Alexandre.Cassen@firewall.loc
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
    router_id MySQL_HA_DEVEL
    vrrp_skip_check_adv_addr
}
  
vrrp_sync_group MySQL_HA_G1 {
     group {
         MySQL_HA_1
     }
}
  
vrrp_script chk_mysql {
     script  "/etc/keepalived/scripts/check_mysql.sh"
     interval 6
     fall 2
     rise 1
     weight 20
}
  
vrrp_script chage_status {
     script  "/etc/keepalived/scripts/chage_status.sh"
     interval 20
}
  
vrrp_instance MySQL_HA_1 {
     state BACKUP
     interface eth1
     virtual_router_id 176
     priority 90
     advert_int 2
     authentication {
         auth_type PASS
         auth_pass v262aR1dqH5jTykUbwTo
     }
  
     virtual_ipaddress {
         192.168.6.176 /24  dev eth1
     }
  
     track_script {
         chk_mysql
         chage_status
     }
  
     track_interface {
         eth1
     }
     notify_master  "/etc/keepalived/scripts/notify.sh master"
     notify_backup  "/etc/keepalived/scripts/notify.sh backup"
     notify_fault   "/etc/keepalived/scripts/notify.sh fault"
     notify_stop    "/etc/keepalived/scripts/notify.sh stop"
}


3、Keepalived notify脚本

    notify脚本是keepalived集群管理脚本,当keepalived角色state状态发生变化时都会执行这个脚本

1
2
3
4
notify_master:当节点进入MASTER时执行该脚本
notify_backup:当节点进入BACKUP时执行该脚本
notify_fault: 当节点进入FAULT时执行该脚本
notify_stop:  当节点进入STOP时执行该脚本

    Server1和Server2的notify脚本定义如下:

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/bin/bash
# Author: hm  Email: mail@huangming.org
LOGDIR= /usr/local/keepalived/logs
LOGFILE= "/usr/local/keepalived/logs/notify_scripts.log"
IPADDR=` ifconfig  eth1 |  awk  -F "[: ]+"  '/inet addr/{print $4}' `
VIP= "192.168.6.176"
[ -d $LOGDIR ] ||  mkdir  $LOGDIR
  
#MASTER
master() {
if  [ ` df  -h | grep  "/dev/sdb1" | wc  -l` - eq  0 ]; then
     echo  "`date '+%b  %d %T %a'` $HOSTNAME [keepalived_notify_script]: mount /dev/sdb1 /data ..."
     mount  /dev/sdb1  /data  &&  sleep  1
else
     echo  "`date '+%b  %d %T %a'` $HOSTNAME [keepalived_notify_script]: /data is mounted on /data"
fi
  
killall -0 mysqld &> /dev/null
if  [ $? - ne  0 ]; then
     echo  "`date '+%b  %d %T %a'` $HOSTNAME [keepalived_notify_script]: /etc/init.d/mysqld start..."
     /etc/init .d /mysqld  start &> /dev/null
else
     echo  "`date '+%b  %d %T %a'` $HOSTNAME [keepalived_notify_script]: Mysqld is Running..."
fi
  
exit  0
}
  
#BACKUP
backup() {
killall -0 mysqld &> /dev/null
if  [ $? - eq  0 ]; then
     echo  "`date '+%b  %d %T %a'` $HOSTNAME [keepalived_notify_script]: /etc/init.d/mysqld stop..."
     /etc/init .d /mysqld  stop &> /dev/null
else 
     echo  "`date '+%b  %d %T %a'` $HOSTNAME [keepalived_notify_script]: Mysql Server is Not Running..."
fi
  
if  [ ` df  -h | grep  "/dev/sdb1" | wc  -l` - ne  0 ]; then
     echo  "`date '+%b  %d %T %a'` $HOSTNAME [keepalived_notify_script]: umount /data..."
     umount  /data  &&  sleep  1
else 
     echo  "`date '+%b  %d %T %a'` $HOSTNAME [keepalived_notify_script]: /data is not mount"
fi
}
  
notify_master() {
     echo  "`date '+%b  %d %T %a'` $HOSTNAME [keepalived_notify_script]: Transition to $1 STATE" ;
     echo  "`date '+%b  %d %T %a'` $HOSTNAME [keepalived_notify_script]: Setup the VIP on eth1 for $VIP" ;
}
  
notify_backup() {
     echo  "`date '+%b  %d %T %a'` $HOSTNAME [keepalived_notify_script]: Transition to $1 STATE" ;
     echo  "`date '+%b  %d %T %a'` $HOSTNAME [keepalived_notify_script]: removing the VIP on eth1 for $VIP" ;
}
  
case  $1  in
         master)
                 notify_master MASTER >>$LOGFILE
                 master >>$LOGFILE
                 exit  0
         ;;
         backup)
                 notify_backup BACKUP >>$LOGFILE
                 backup >>$LOGFILE
                 exit  0
         ;;
         fault)
                 notify_backup FAULT >>$LOGFILE
backup >>$LOGFILE
                 exit  0
         ;;
         stop)
                 notify_backup STOP >>$LOGFILE
                 backup >>$LOGFILE
                 #/etc/init.d/keepalived restart &>/dev/null  #这一项仅在Server2节点上配置
                 exit  0
         ;;
         *)
                 echo  "Usage: `basename $0` {master|backup|fault|stop}"
                 exit  1
         ;;
esac


4、keepalived资源检测脚本

    MySQL服务检测脚本check_mysql.sh

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
# 检测共享磁盘是否正常挂载,如果没有挂载,则脚本返回状态码1
if  [ ` df  -h | grep  "/dev/sdb1" | wc  -l` - eq  0  ]; then
exit  1
#检测MySQL服务是否正常运行,如果不正常,则返回状态码1
elif  ! killall -0 mysqld &> /dev/null ; then
     exit  1
else
     exit  0
Fi
# 如果共享磁盘和MySQL服务都正常,那么就返回0,进入keepalived集群的MASTER或BAKUP角色

    MySQL更改状态脚本chage_status.sh(MASTER)

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
#!/bin/bash
# in MASTER
#改变MySQL服务的检测脚本,keepalived刚启动时,Server1节点接管MySQL服务,成为MASTER,该节
#点的检测mysql服务脚本为正常检测,即当共享磁盘和MySQL服务均正常,则正常返回状态码0;
#而Server2节点,在启动keepalived时,检测脚本则改为当共享磁盘和MySQL服务均没有运行时,
#同样返回状态码0,因此进入BACKUP角色。改变检测脚本的前提条件为是否存在VIP,当Server2节点
#同时满足这三个条件才会改变脚本的检测状态
 
CHK_VIP=`ip addr|  awk  -F "[ :]+"  '/192.168.6.176/{print $3}' `
if  "$CHK_VIP"  ==  ""  ]; then
cat  /etc/keepalived/scripts/check_mysql .sh << EOF
#!/bin/bash
if  [ \` df  -h | grep  "/dev/sdb1" | wc  -l\` - eq  0  ]; then
     exit  0
elif  ! killall -0 mysqld &> /dev/null ; then
     exit  0
else
     exit  0
fi
EOF
else
cat  /etc/keepalived/scripts/check_mysql .sh << EOF
#!/bin/bash
if  [ \` df  -h | grep  "/dev/sdb1" | wc  -l\` - eq  0  ]; then
     exit  1
elif  ! killall -0 mysqld &> /dev/null ; then
     exit  1
else
     exit  0
fi
EOF
Fi

MySQL更改状态脚本chage_status.sh(BACKUP)

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
#!/bin/bash
# in BACKUP
CHK_VIP=`ip addr|  awk  -F "[ :]+"  '/192.168.6.176/{print $3}' `
if  "$CHK_VIP"  ==  ""  ]; then
cat  /etc/keepalived/scripts/check_mysql .sh << EOF
#!/bin/bash
if  [ \` df  -h | grep  "/dev/sdb1" | wc  -l\` - eq  0  ]; then
     exit  0
elif  ! killall -0 mysqld &> /dev/null ; then
     exit  0
else
     exit  0
fi
EOF
else
cat  /etc/keepalived/scripts/check_mysql .sh << EOF
#!/bin/bash
if  [ \` df  -h | grep  "/dev/sdb1" | wc  -l\` - eq  0  ]; then
     exit  1
elif  ! killall -0 mysqld &> /dev/null ; then
     pkill keepalived &&  exit  1
else
     exit  0
fi
EOF
fi


本文转自 HMLinux 51CTO博客,原文链接:http://blog.51cto.com/7424593/1893767


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
存储 关系型数据库 MySQL
Mysql高可用|索引|事务 | 调优
Mysql高可用|索引|事务 | 调优
|
3月前
|
SQL 容灾 关系型数据库
rds容灾与高可用
rds容灾与高可用
28 4
|
3月前
|
关系型数据库 MySQL
电子好书发您分享《MySQL MGR 8.0高可用实战》
电子好书发您分享《MySQL MGR 8.0高可用实战》 电子好书发您分享《MySQL MGR 8.0高可用实战》
90 1
|
2月前
|
SQL 运维 关系型数据库
如何对比MySQL主备数据的一致性?
如何在数据库世界中处理大批量数据变更操作,而不影响业务运行。NineData的OnlineDML解决方案通过无锁方式实现数据变更,确保在线业务的顺畅运行。只需两步操作即可开启OnlineDML功能,让NineData自动处理大型DML操作,分批执行并根据数据库压力进行智能调整,简化操作流程并提供直观操作界面。
322 2
如何对比MySQL主备数据的一致性?
|
1月前
|
SQL 关系型数据库 MySQL
923.【mysql】 only full group by 模式
923.【mysql】 only full group by 模式
20 1
|
2月前
|
存储 监控 关系型数据库
mysql 主备延迟的原因及解决思路,优化方法
MySQL 主备延迟(replication delay)是指主服务器(master)上的数据更新操作与备服务器(slave)上相同数据更新操作之间的时间差。这种延迟可能会导致数据不一致,影响系统的可用性和可靠性。以下是主备延迟的常见原因、解决思路和优化方法: ### 常见原因 1. **网络延迟**:主备服务器之间的网络不稳定或带宽不足。 2. **硬件性能**:备服务器的硬件性能不足,如 CPU、内存、磁盘 I/O 等。 3. **大量数据写入**:主服务器上的大量数据写入操作导致备服务器难以同步。 4. **复杂的查询**:备服务器执行复杂的查询操作,影响同步速度。 5. **二进制
|
2月前
|
监控 容灾 关系型数据库
rds容灾与高可用
rds容灾与高可用
46 6
|
3月前
|
SQL 关系型数据库 MySQL
Mysql高可用,索引,事务与调优:提高数据库性能的关键技术
在当今互联网时代,高可用性、稳定性和性能是数据库的三大关键要素。本文将深入探讨Mysql高可用、索引、事务和调优等方面的技术,为读者提供实用的解决方案和经验。
24 0
|
11天前
|
关系型数据库 MySQL 数据库
mysql卸载、下载、安装(window版本)
mysql卸载、下载、安装(window版本)
|
29天前
|
关系型数据库 MySQL 数据库
rds安装数据库客户端工具
安装阿里云RDS的数据库客户端涉及在本地安装对应类型(如MySQL、PostgreSQL)的客户端工具。对于MySQL,可选择MySQL Command-Line Client或图形化工具如Navicat,安装后输入RDS实例的连接参数进行连接。对于PostgreSQL,可以使用`psql`命令行工具或图形化客户端如PgAdmin。首先从阿里云控制台获取连接信息,然后按照官方文档安装客户端,最后配置客户端连接以确保遵循安全指引。
82 1