keep alived + MySQL 双主复制

MySQL双主复制

双主复制的原理

MySQL双主架构是一种比较简单的高可用架构,基于MySQL源生的主从同步实现,两个服务器互为对方的备库,同时两个服务器又都可以承接写任务。上层通过keepalived 实现vip 的自动切换,提供高可用服务。

双主复制的优缺点
  • 优点
    1. 架构简单,基于MySQL自带的主从同步实现,部署容易
    2. 节省资源,同时可以满足普通业务的需要
    3. 互为备库,保证数据安全
  • 缺点
    1. 基于MySQL主从同步,存在延迟,如果使用半同步复制,会对主库造成影响
    2. MySQL双主架构中没有冲突检测机制,容易出现主键冲突 ,造成同步失败
    3. 存在出现脑裂的风险
    4. 扩展复杂,如果主键在应用层使用mod 生成,每次扩展需要修改程序代码。

keepalived

keepalived 原理

keepalived 使用vrrp 协议,实现了路由功能的高可用(区别于Heartbeat或Corosync实现的的Service高可用)。
keepalived 主要又三个进程:主进程,vrrp 进程,healthcheckers 进程,
两个子进程都有watchdog 模块监控,其中vrrp 进程主要是负责vip和mac地址的映射,vip 的摘除等工作;checkers 进程主要负责的是系统的健康状态探测。

keepalived 可以使用shell 脚本对指定的进程或者服务进行简单的监控,如果资源或者服务不可用可以直接在脚本中停掉keepalived 主进程,来实现VIP的自动切换。

keepalived 部署
  1. 双主复制环境准备(略)
  2. 安装keepalived (rpm安装)
  3. 配置keepalived

主要的文件如下:

keepalived 配置文件:
主库的配置文件:

    # cat /etc/keepalived/keepalived.conf 
    vrrp_script chk_mysql {
        script "/etc/keepalived/check_mysql.sh"
        interval 5
    }
    vrrp_instance VI_1 {
        state BACKUP
        interface eth0
        virtual_router_id 51
        priority 100
        advert_int 1
        nopreempt
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        track_script {
            chk_mysql
        }
         
        virtual_ipaddress {
            12.3.10.222/24
        }
    }

从库的配置文件,主从的差异主要是,从库在切换到主库之后,需要执行notify_master_mysql.sh ,该脚本的内容在后面

# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived
 
vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    notify_master /etc/keepalived/notify_master_mysql.sh
    virtual_ipaddress {
        12.3.10.222/24
    }
}

mysql 服务的检查脚本,keepalived 会执行脚本,检查MySQL的服务是不是正常,该脚本根据实际情况修改,主要的内容例如:检查MySQL服务,检查keepalived 是否异常,ping 网关检查等。此示例中简配。

# cat check_mysql.sh 
#!/bin/bash
mysql_conn='mysql -uroot -p123456'
$mysql_conn -e "show master status " >>/dev/null 2>&1
if [ $? -ne 0 ];
	then 
	killall keepalived
fi

备库切换为主库要进行的操作,主要是判断binlog的应用和开启读写功能。

# cat notify_master_mysql.sh 
#!/bin/bash
###当keepalived监测到本机转为MASTER状态时,执行该脚本
 
change_log=/etc/keepalived/logs/state_change.log
mysql_con='mysql -uroot -p123456'
echo -e "`date "+%F  %H:%M:%S"`   -----keepalived change to MASTER-----" >> $change_log
 
slave_info() {
    ###统一定义一个函数取得slave的position、running、和log_file等信息
    ###根据函数后面所跟参数来决定取得哪些数据
    if [ $1 = slave_status ];then
        slave_stat=`${mysql_con} -e "show slave status\G;"|egrep -w "Slave_IO_Running|Slave_SQL_Running"`
        Slave_IO_Running=`echo $slave_stat|awk '{print $2}'`
        Slave_SQL_Running=`echo $slave_stat|awk '{print $4}'`
    elif [ $1 = log_file -a $2 = pos ];then
        log_file_pos=`${mysql_con} -e "show slave status\G;"|egrep -w "Master_Log_File|Read_Master_Log_Pos|Relay_Master_Log_File|Exec_Master_Log_Pos"`
        Master_Log_File=`echo $log_file_pos|awk '{print $2}'`
        Read_Master_Log_Pos=`echo $log_file_pos|awk '{print $4}'`
        Relay_Master_Log_File=`echo $log_file_pos|awk '{print $6}'`
        Exec_Master_Log_Pos=`echo $log_file_pos|awk '{print $8}'`
    fi
}
 
action() {
    ###经判断'应该&可以'切换时执行的动作
    echo -e "`date "+%F  %H:%M:%S"`    -----set read_only = 0 on DB2-----" >> $change_log
 
    ###解除read_only属性
    ${mysql_con} -e "set global read_only = 0;" 2>> $change_log
 
#    echo "DB2 keepalived转为MASTER状态,线上数据库切换至DB2"|mail -s "DB2 keepalived change to MASTER"\
#    slowtech@126.com 2>> $change_log
 
    echo -e "---------------------------------------------------------\n" >> $change_log
}
 
slave_info slave_status
if [ $Slave_SQL_Running = Yes ];then
    i=0    #一个计数器
    slave_info log_file pos
        ###判断从master接收到的binlog是否全部在本地执行(这样仍无法完全确定从库已追上主库,因为无法完全保证io_thread没有延时(由网络传输问题导致的从库落后的概率很小)
    until [ $Master_Log_File = $Relay_Master_Log_File -a $Read_Master_Log_Pos = $Exec_Master_Log_Pos ]
     do
        if [ $i -lt 10 ];then    #将等待exec_pos追上read_pos的时间限制为10s
            echo -e "`date "+%F  %H:%M:%S"`    -----Relay_Master_Log_File=$Relay_Master_Log_File,Exec_Master_Log_Pos=$Exec_Master_Log_Pos is behind Master_Log_File=$Master_Log_File,Read_Master_Log_Pos=$Read_Master_Log_Pos, wait......" >> $change_log    #输出消息到日志,等待exec_pos=read_pos
            i=$(($i+1))
            sleep 1
            slave_info log_file pos
        else
            echo -e "The waits time is more than 10s,now force change. Master_Log_File=$Master_Log_File Read_Master_Log_Pos=$Read_Master_Log_Pos Relay_Master_Log_File=$Relay_Master_Log_File Exec_Master_Log_Pos=$Exec_Master_Log_Pos" >> $change_log
            action
            exit 0
        fi
    done
    action 
 
else
    slave_info log_file pos
    echo -e "DB2's slave status is wrong,now force change. Master_Log_File=$Master_Log_File Read_Master_Log_Pos=$Read_Master_Log_Pos Relay_Master_Log_File=$Relay_Master_Log_File Exec_Master_Log_Pos=$Exec_Master_Log_Pos" >> $change_log
    action
fi

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值