赞
踩
上节介绍的主、从切换实践,其实现方式和逻辑虽然简单并且相对可靠,但是毕竟费时又费力,甚至在很多情况下还会出现人为误操作的问题。那么是否存在某种方式可以尽量避免这类事件的发生呢,有一种显而易见的方式就是用程序代替人工来实现切换操作。本节将介绍如何基于开源软件Keepalived以及定制开发的轻量级脚本来实现这一需求。
Keepalived 安装
Keepalived 介绍
Keepalived开源软件可以在TCP/IP栈的IP层、TCP层及应用层工作,支持类似于交换机制软件中通常所说的第3层、第4层和第5层交换。通过使用虚拟路由冗余协议(VRRP),Keepalived集群可以共用一个对外提供服务的VIP。在此集群中,主(master)服务器(单台)通过多播或单播方式与备份(backup)服务器(单台或多台)进行通信,建立心跳,并确认双方是否存活。如果其中的master主机宕机或者出现异常,那么集群中其他的backup主机则会通过VRRP协议选举出新的master主机,以此来防止单点故障并实现服务的高可用性。
在业界,Keepalived被广泛应用于LAMP或LNMP等应用软件组合的后端架构中。
Keepalived主要包含三个模块:
CORE模块:负责主进程的启动、维护及全局配置文件的加载和解析;
CHECK模块:负责健康检查,支持使用自主开发的脚本或程序实现特定的监控与检测;
VRRP模块:用于实现虚拟路由冗余协议。Keepalived的健康检查与心跳检测两大特性可用于实现MySQL的自动切换。
Keepalived 安装
Keepalived软件安装主要有RPM包和源码编译两种方式。像CentOS开源系统平台,可直接使用RPM包方式安装,这是我们推荐使用的方式。对于其他平台,则可使用编译方式实现。
首先,安装Keepalived相关依赖包,命令如下:
shell> yum install -y openssl openssl-devel libnl libnl-devel libnfnetlink
shell> wget http://mirror.centos.org/centos/7/os/x86_64/Packages/libnfnetlink-devel-1.0.1-4.el7.x86_64.rpm
shell> rpm -ivh libnfnetlink-devel-1.0.1-4.el7.x86_64.rpm
采用RPM包方式安装(推荐),命令如下:
shell> yum install -y keepalived
或者,采用编译方式安装,命令如下:
shell> test -d /usr/local/keepalived || mkdir /usr/local/keepalived
shell> cd /soft
shell> wget http://www.keepalived.org/software/keepalived-1.3.5.tar.gz
shell> tar -zxvf keepalived-1.3.5.tar.gz
shell> cd ./keepalived-1.3.5/
shell> ./configure --prefix=/usr/local/keepalived
shell> make && make install
shell> mkdir /usr/local/keepalived/var
shell> ln -s /run /usr/local/keepalived/var/run
注意:源码编译过程中,若出现configure: error: libnfnetlink headers missing,则意味着libnfnetlink-devel包缺失。由于操作系统ISO镜像中并不包含此包,因此需要单独下载并安装。
准备Mysql 检查脚本及主从切换脚本
在具体配置Keepalived之前,CHECK模块要调用的mysql_check.sh脚本需要提前准备好。该脚本会按照Keepalived配置中指定的时间间隔,定期检查MySQL实例的运行状态,并将检查结果记录到输出日志中以方便回溯。需要注意的是,本节介绍的脚本均采用Linux原生最兼容的bash语言开发。mysql_check.sh脚本如下:
shell> mkdir -p /etc/keepalived/{scripts,log}
shell> vi /etc/keepalived/scripts/mysql_check.sh
#!/bin/bash
. $HOME/.bash_profile >/dev/null 2>&1
LogDir=/etc/keepalived/log
logfile=$LogDir/mysql_check.log
Lhost=localhost
Luser=root
Lpasswd=Abcd321#
Lsocket=/mysql/product/data/mysql.sock
ConnCMD="-h$Lhost -u$Luser -p$Lpasswd -S$Lsocket"
shopt -s expand_aliases
alias cdate='date +"%Y-%m-%d %H:%M:%S"'
InstSuffix=''
startMySQLcmd="systemctl start mysqld$InstSuffix"
stopKeepAliveDcmd="systemctl stop keepalived"
WaitTime=5
WaitCount=12
j=1
while true
do
mysqld_status=`mysqladmin $ConnCMD ping 2>/dev/null`
mysql_status=`mysql $ConnCMD -e"select 1;" 2>/dev/null|awk 'NR>1'`
if [ "$mysqld_status" == "mysqld is alive" ] && [ $mysql_status -eq 1 ];then
echo "$(cdate) [Note] MySQL Service is Normal." >> $logfile
exit 0
elif [ "$mysqld_status" == "mysqld is alive" ] && [ $mysql_status -ne 1 ];then
echo "$(cdate) [Warning] MySQL Service may be Hung." >> $logfile
exit 0
else
if [ $j -le $WaitCount ];then
echo "$(cdate) [Error] MySQL Service is Abnormal and will be restart." >> $logfile
$startMySQLcmd
else
echo "$(cdate) [Error] MySQL Service is still Abnormal After $WaitCount restarts."
>> $logfile
$stopKeepAliveDcmd
echo "$(cdate) [Action] KeepAlived is forced to perform a Failover." >> $logfile
break
fi
fi
sleep $WaitTime
let j++
done
使用Keepalived检查模块调用mysql_check.sh&
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。