目录
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_1vrrp_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 status\G;\" | 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 status\G;\" | grep File | cut -d: -f2 | tr -d \" \""` # 配置主机复制备机 sudo $MYSQL_EXCUTE -u${dbuser} -p${DB_PASSWD} --socket=${MYSQL_SOCK} mysql <