1. 容灾的基本认识
1.1 概念
容灾系统是指在相隔较远的异地,建立两套或多套功能上相同的系统。
一个系统处于正常的运行状态,对外提供服务(主机),担任备份功能的系统则称为备机。
当主机系统因意外(火灾、洪灾等)停止工作时,可以切换到备机系统对外提供服务,使整个软件系统具备高可用的特征。
1.2 分类
容灾可以分为数据级容灾和应用级容灾。
数据容灾是指建立一个异地数据系统,对本地关键应用数据进行实时复制。做数据(数据库/文件)的远程备份。
应用容灾是在数据容灾基础上,在异地建立一套完整的与本地系统相当的备份应用系统。
在本地系统受灾时,可以迅速接管业务运行,保障业务连续性。
三分钟掌握数据中心“容灾和备份的区别
2. 项目中容灾系统的架构
2.1 组网图
2.2 基于Veritas实现容灾
略
2.3 基于Keepalived+MySQL+ rsync实现容灾备份
2.3.1 基于keepalived的服务器主备节点选举
1、kpld的配置
! Configuration File for keepalived
# 全局配置
global_defs {
router_id eomc-131_MASTER
script_user eoss
enable_script_security
}
# VRRP同步组配置
vrrp_sync_group GROUP_FOR_MULTI_PLANE {
group {
# 不同网段实例的检测,出现故障时切换。
VI_1
}
}
# VRRP实例配置:实例名称VI_1
vrrp_instance VI_1 {
# 指定kpld角色:MASTER/BACKUP
state BACKUP
# 指定HA检测网口
interface eth1
#虚拟路由标识,同意VRRP实例使用唯一标识。即主备机必须一致。
virtual_router_id 243
#设置发送多播包的地址
mcast_src_ip 168.1.90.131
priority 120
# 主备机之间同步检查时间间隔(s)
advert_int 40
# 不抢占。主节点故障恢复后不再切回到主节点,就在备节点运行。
# 只能在state为BACKUP的节点上设置(因为是BACKUP节点决定是否来成为MASTER的),且优先级必须高于其他节点。
#(主备机都设成BACKUP+nopreempt,实现不抢占(关闭auto_failback))
nopreempt
# kpld通知机制
notify_master /opt/HA/bin/master.sh
notify_backup /opt/HA/bin/slave.sh
notify_fault /opt/HA/bin/fault.sh
# 虚拟IP,kpld切换成MASTER时,vip会自动添加到系统。切换到BACKUP,vip自动删除。
virtual_ipaddress {
168.1.90.243/24 brd 168.1.90.255 dev eth1 scope global
}
}
2.3.3 数据库同步:mysql双主互备模式
2.3.2 文件同步:inotify + rsync实现远程文件同步
3. 问题记录
3.1 出现双主(主备机服务都在运行)恢复后数据库会存在脏数据。
原因:主备机服务都在运行,都会向本机MySQL写入数据。
方案1.
主备机主键自增奇/偶区分或生成全局唯一id,确保不冲突。 ==> 能解决主键冲突,但是不能保证业务数据一致性。(例:主机的断连告警已经恢复,备机的断连告警又上报了。同步后就存在问题。)
方案2.
检测到另一端服务器连不上时,停止数据库复制操作( stop slave),
连接恢复后,判断断开期间是否出现双主,没有则恢复复制。
3.2 客户的特殊应用场景
xx项目由于当地每年有洪灾的风险,所以使用了异地容灾场景。
但是,备机处于长时间下电状态,只有在洪涝灾害季节才被备机房上电。
客户同样希望上电后就可以达到容灾的效果。切换到备机后也能快速提供服务,并且数据是同步的。
But,由于数据平时没有同步,上电后才开始同步。如果超过一定时间未复制数据,主机binlog有自动清理机制(例如只保留3天),故binlog可能并不完整,导致备机上电切换成主机的场景会出现数据丢失问题。
解决方案:
方案1. (选择)
备机上电以后,(如果发现自己与世隔绝了很久)自动进行一次数据库全量同步操作。完成后从主机备份的最后position,开始binlog数据复制。保证同步数据的完整性。
方案2.
客户需要在一定时间内把备机房上电一定时间,触发数据自动同步。上电操作可以是定时触发,也可以是binlog文件占用多大以后上报致命告警,要求客户上电。
主备数据同步脚本参考:
# step1 停复制
# 略
# step2 数据库全量数据同步 xtrabackup
# 略
# step3 复制同步 复制权限授权,并从全量同步的最后position开始slave复制。
logpos=`sudo -u eoss ssh eoss@$REMOTE_IP "sudo $MYSQL_EXCUTE -u${dbuser} -p${DB_PASSWD} --socket=${MYSQL_SOCK} -e" show master statusG;" | grep Position | cut -d: -f2 | tr -d " ""`
logname=`sudo -u eoss ssh eoss@$REMOTE_IP "sudo $MYSQL_EXCUTE -u${dbuser} -p${DB_PASSWD} --socket=${MYSQL_SOCK} -e" show master statusG;" | grep File | cut -d: -f2 | tr -d " ""`
# 配置主机复制备机
sudo $MYSQL_EXCUTE -u${dbuser} -p${DB_PASSWD} --socket=${MYSQL_SOCK} mysql <<EOF
stop slave;
reset slave;
CHANGE MASTER TO MASTER_HOST='${REMOTE_IP}', MASTER_PORT=3308, MASTER_USER='backup', MASTER_PASSWORD='${BACKUP_PASSWD}', MASTER_CONNECT_RETRY=60, MASTER_LOG_FILE='$logname', MASTER_LOG_POS=$logpos;
unlock tables;
start slave;
EOF
# step 4 rsync文件同步
# 略