一、背景
某次与同事讨论Linux运维中的备份解决方案,一般日常为简单省事,采用脚本计划性备份到本地,有的会scp到异地;该同事刚好项目遇到底层磁盘阵列60多块盘集体故障的事,遂就谈到如何保证数据的高可用,除了底层做RAID外,上层LVM,其他的呢?于是,就谈到,可以写一份数据到某一服务器,然后通过技术手段异步到异地,最好实时,最好可增量备份,最好可去重,自带数据一致性监测机制。于是,就有了本文以下整理汇总;关于备份数据源和目标数据一致性监测机制,异步实施传输问题,烦请相关经验的同学路过,各抒己见,讨论交流,此致敬礼!
二、备份策略
2.1、完全备份(Full Backup)
即把所有需要备份的数据全部备份,所谓的‘整备’,可以备份整块硬盘、整个分区或某个具体的目录。方式:快照(不推荐),副本(镜像/克隆),利用dd命令创建镜像,tar整体打包目录或分区,
好处:恢复简单,效率较高。
缺点:需要备份的数据量较大,备份时间较长,恢复时间也较长,占用的空间较大,一般不按日执行备份,
命令:dd命令,dd 命令可以把源数据复制成目标数据,而且不管源数据是文件、分区、磁盘还是光盘,都可以进行数据备份。果要备份文件,那么dd命令和cp命令非常类似;如果想要把分区直接备份成另一个分区,就需要生成一个新的分区,这个分区的大小不能比源分区小,只能和源分区大小一致或比它大。注:dd 命令有一个明显的缺点,就是复制的时间较长,有经验表明复制 100GB 的数据需要 15~25 分钟,可以考虑tar 和 cpio 命令,对于网络复制工具,如 rsync 和 scp;
#格式:dd if="输入文件" of="输出文件" bs="数据块" count="数量"
#备份boot分区
dd if=/dev/sda1 of=/tmp/boot.bak
dd if=/tmp/boot.bak of=/dev/sda1 #恢复
dd if=/dev/sda of=/dev/sdb #把磁盘a备份到磁盘b
dd if=/dev/cdrom of-/tmp/cd.iso #把光盘中所有的数据制作成ISO镜像
mount -o loop /tmp/cd.iso /mnt/cd #验证,挂栽ISO文件到挂载点
dd if=/dev/zero of=/tmp/testfile bs=1M count=10 #创建10M的临时块文件
2.2、差异备份(Differential Backup)
先进行一次完全备份,此后,每次只备份相对于该“完备”新增的那部分数据,相当于1+x的模式,主要关注X中的数据,差异备份每次备份的参照物都是原始的完全备份,而非上一次的差异备份。示意图如下:
差异备份既不像完全备份一样把所有数据都进行备份,也不像增量备份在进行数据恢复时那么麻烦,只要先恢复完全备份的数据,再恢复差异备份的数据即可。不过,随着时间的增加,和完全备份相比,变动的数据越来越多,那么差异备份也可能会变得数据量庞大、备份速度缓慢、占用空间较大。
2.3、增量备份(Incremental Backup )
它是指先进行一次完全备份,服务器运行一段时间之后,比较当前和上一次完全备份的备份数据之间的差异,只备份差异部分的数据。第二次增量备份是,在对比当前相对与当一次增量+完全那部分差额的数据。第三次备份,对比 1+x1+x2 后的数据,依次类推,完成1+x1+x2+……+xn 一次完备+n次增量。以后每次的备份只需备份与前一次相比增加和者被修改的文件。这就意味着,第一次增量备份的对象是进行全备份后所产生的增加和修改的文件;第二次增量备份的对象是进行第一次增量备份后所产生的增加和修改的文件,如此类推。
好处:没有重复的备份数据,备份的数据量不大,备份所需的时间很短。
缺点:恢复复杂,需要按顺序恢复,一旦中间的任何一个环节出现错误,都将导致无法还原;
命令:dump 命令使用“备份级别”来实现增量备份,它支持 0~9 共 10 个备份级别。其中,0 级别指的就是完全备份,1~9 级别都是增量备份级别。当我们备份一份数据时,第一次备份应该使用 0 级别,会把所有数据完全备份一次;第二次备份就可以使用 1 级别了,它会和 0 级别进行比较,把 0 级别备份之后变化的数据进行备份;第三次备份使用 2 级别,2 级别会和 1 级别进行比较,把 1 级别备份之后变化的数据进行备份,以此类推。dump命令可以非常方便地实现增量备份。如果,先使用 0 级别完全备份一次,以后的每次备份都使用 1 级别进行备份,这时就变成了差异备份。restore 命令是 dump 命令的配套命令,dump 命令是用来备份分区和数据的,而 restore 命令是用来恢复数据的。restore 命令的还原模式既可以用于还原整个分区,也可以用于还原文件或目录。命令格式是一样的,不过要注意,如果要还原增量备份的数据,则一定要先还原完全备份的数据。
需要注意的是,只有在备份整个分区或整块硬盘时,才能支持 1~9 的增量备份级别;如果只是备份某个文件或不是分区的目录,则只能使用 0 级别进行完全备份。
#备份/boot/分区,以下命令会先执行一次完全备份,并压缩和更新备份时间
dump -0uj -f /root/boot.bak.bz2 /boot/ #0完全备份,u:备份成功之后,把备份时间、备份级别以及实施备份的文件系统等信息,都记录在 /etc/dumpdates 文件中;-j:调用 bzlib 库压缩备份文件,其实就是把备份文件压缩为 .bz2 格式,默认压缩等级是 2;
cat /etc/dumpdates #查看备份时间文件
dump -1uj -f /root/boot.bak1.bz2 /boot/ #1级增量备份
dump -W #命令来查询分区的备份时间及备份级别,但如果备份时没有使用“-u”选项,那么“dump -W”命令是不会记录备份的时间和级别的
#恢复
restore -C -f /root/boot.bak.bz2 #检测备份,-C:比较备份数据和实际数据的变化。如果实际数据中的现有数据发生了变化,那么这个选项能够检测到这个变化。但是如果实际数据中新增了数据,那么这个选项是不能检测到变化的。即-C参数只能检测原有数据的变化,无法检测新增
restore -t -f boot.bak.bz2 #查看备份文件中到底包含什么内容
#还原boot.bak.bz2分区备份,先还原完全备份的数据
restore -r -f /root/boot.bak.bz2 #-r:还原模式,用于数据还原
#再还原增量备份的数据
restore -r -f /root/boot.bak1.bz2
#附录:
cpio命令可以备份从标准输入( stdin )而来的的档案
增量备份与差异备份的区别在于它们备份的参考点不同:前者的参考点是上一次完全备份、差异备份或增量备份,后者的参考点是上一次完全备份。
注:如果新添加或更改的文件包含的数据比原始文件多,即增量文件多,原始文件少,则差异备份和增量备份都比初次完全备份慢。
☛ 备份策略建议:对于数据量不大,并且每天数据量增加不多的系统,优先选择完全备份;对于数据量巨大,每天新增数据也很多的系统,视情况选择差异备份或者增量备份。
2.4、恢复策略
常见的恢复方法:
近点恢复:使用 tar 命令可以将备份的 tar 包还原到原来的位置,其语法格式如下:tar -xvf 。
增量恢复:使用 rsync 命令可以将备份文件还原到原来的位置,其语法格式如下:rsync -avz 。
全文件恢复:使用 duplicity 命令可以将备份文件还原到原来的位置,其语法格式如下:duplicity –full 。
三、实现方案
3.1 本地备份+异地同步:rsync +inotify
rsync:它是类unix系统下的数据镜像备份工具——remote sync。它是一款快速增量备份工具 Remote Sync,只针对修改过的文件的修改过的部分进行同步备份,大大缩短了传输的文件的数量和传输时间,支持远程同步,支持本地复制,或者与其他SSH、rsync主机同步。rsync只是一次性同步,如果需要实时同步就需要引入另一个工具inotify,inotify是一种强大的、细粒度的、异步的文件系统事件监控机制。安装inotify软件的主机会监听服务器端的主机是否数据和本机不一样,如不一样就用rsync命令直接把数据传输过去。客户端安装rsync软件是为了调用rsync的命令,安装inotify软件是监听和数据是否发生改变,服务器端安装rsync软件时为了提供rsync服务。另,使用 rsync 命令备份数据时,不会直接覆盖以前的数据(如果数据已经存在),而是先判断已经存在的数据和新数据的差异,只有数据不同时才会把不相同的部分覆盖。
特性:
可以镜像保存整个目录树和文件系统
可以同步增量同步数据,文件传输效率高,因而同步时间很短
可以保持原有文件的权限、时间等属性
加密传输数据,保证了数据的安全性
支持匿名传输
用法:rsync src dest
参数: 常用 avz
-a: archive (归档)mode, 等同于-rlptgoD, -a选项后面可以跟一个 –no-OPTION ,表示关闭-rlptgoD中的某一个例如 -a–no-l 等同于-rptgoD
-r: 递归同步,主要是针对目录来说的,如果单独传一个文件不需要加-r,但是传输的是目录必须加-r选项
–delete:删除 DEST 中 SRC 没有的文件,如果src没有此文件,那么dest也不能有,即在dest删除src里没有的文件。(如果你使用这个选项,就必须搭配-r选项一起)
-p: 同步时保留原文件的权限设置
–P:在同步的过程中可以看到同步的过程状态,比如统计要同步的文件数量、同步的文件传输速度等等
-t: 将src的修改时间,同步到dest,保持文件时间信息
-g: 同步组信息(group)
-o: 同步拥有者信息(own)
-D: 保持字符与块设备文件
-u: 若文件在远端做过更新,则不同步,避免覆盖远端的修改,DST中比SRC还新的文件排除掉,不会覆盖
-n:模拟将要执行的操作
-l:保留软链结
-L: 同步符号链接链接的文件,防止在远程服务器出现文件路径等不匹配导致的软连接失效
-t: 保留修改时间
-v: 显示更新信息
-z: 传输过程中压缩文件,对于传输速度慢时适用
–exclude=PATTERN :指定排除不需要传输的文件,等号后面跟文件名,可以是通配符模式(如 *.txt)
–remove-source-files:删除源已经成功传输的文件,如果传输目录则整个目录及内容传输到目标目录,仍会保留一个空的源目录
eg1: 将本地/bak/mysqlbak/文件同步到 远程服务器 /bak/mysql/bak 目录下面 排除 mysqlbak/index目录 通过ssh端口
yum install -y rsync
rsync -vzacu /bak/mysqlbak/ root@192.168.53.86:/bak/mysqlbak --exclude "mysqlbak/index" -e "ssh -p 22"
eg2:将远程目录 /bak/mysqlbak下的文件同步到本地 /bak/mysqlbak/目录下
rsync -vzrtopg --progress --delete root@192.168.53.85:/bak/mysqlbak /bak
eg3:本地文件同步/复制:
rsync -av /etc/passwd /tmp/1.txt #将 /etc/passwd 文件本地同步到 /tmp/ 目录下,并改名为 1.txt
eg4:同步文件后清理源端
#使用-c该参数后通过判断文件内容的校验和来决定是否进行传输 rsync 默认是以文件的更改日期以及大小是否发生变化来决定是否重新传输,如果发生变化就重传输
#--remove-source-files: 表示传输完毕后,删除发送方的文件,注意该参数有风险,会删除
#--exclude-from 参数指定一个本地文件 里面是需要排除的文件模式,每个模式一行
#-e "ssh -p your_port" 指定 ssh登录 并指定端口号;root@Dest_ip:/dest_dir :用户名@ip :/b服务器/数据目录
rsync -c --remove-source-files --exclude-from=rsyncrule.txt -r /src/dir -e "ssh -p your_port" root@Dest_ip:/dest_dir
#规则文件书写格式:
# 代表注释
#- 代表不传输的东西
#+ 代表需要传输的东西
#不传输目录
- */
- .* #不传输隐藏文件
- rsyncrule.txt
#传输指定后缀扩展名的文件这里写成你自己需要传输的文件后缀就可以了
#有多个文件需要传的话,就另起一行继续按格式写就好了
+ *.txt
#禁止传输其他文件
eg5:借用–link-dest参数指定同步时的基准目录,然后将源目录相对与基准目录之间变动的部分,同步到目标目录,实现差异和增量
#--link-dest参数指定基准目录/fullbackup,然后源目录/source/path跟基准目录/compare/path进行比较,找出变动的文件,将它们拷贝到目标目录/target/path。没变动的文件则会生成硬链接,硬链接指向上一个/target/path中的文件。这个命令的第一次备份时是全量备份,后面就都是增量备份了。
rsync -a --delete /data/ /fullbackup #第一次权力备份
rsync -a --delete --link-dest /fullbackup /source/path /target/increment1_path #第一次增量备份,即差异备份;注意,此时的目标目录拥有与当前源目录一模一样的文件,但实际上,这些文件中,只有那些变动过的文件是刚刚新建/备份到该目录中的,其他没有变动的文件都是直接指向基准目录文件的**硬链接**而不是重新拷贝了一份。即对与基准一致的源文件起了一个别名,它们有相同的 inode 及 data block,即指向同一个文件;
rsync -a --delete --link-dest /target/increment1_path /data/ /target/increment2_path #增量备份,相对于全备+第一次差异后的增量部分的备份,依次增量下去,rsync的每次增量都会保留源目录中的全部文件,但是若文件较之上一次没有变化,则新备份中的文件只是创建了一个指向上一次对应文件的硬链接,这就保证了在不浪费空间的前提下,保证了rsync的增量备份在恢复数据时,只需要找到一份备份既可以恢复到指定的状态,使得其数据恢复过程的简洁性与完全备份几乎一样,却比全量备份的数据量要小很多
#增量备份脚本示例
#!/bin/bash
set -o errexit # 它使得脚本只要发生错误,就终止执行,而不是一声不响地往下执行
set -o nounset # 在shell中,遇到变量不存在,并不会报错,而是输出空,然后继续执行后续代码
# 开启nounset选项后,脚本若碰到变量为定义则报错并终止运行
set -o pipefail # 上面的选项errexit针对管道命令是无效的,比如xxx | echo "egon",并不存在
# xxx命令,但是该管道命令整体是执行成功的,加上pipefail选项后则可以防止这件事
readonly SOURCE_DIR="/opt" # 备份的源目录
readonly TARGET_START_DIR="/data2/backups" # 目标目录的根目录;注意:基于rsync的增量备份在恢复数据时,只需要去/data2/backups找对应时间的目录即可,那里面每个目录里存放的就是对应时间节点的所有数据
readonly TARGET_DIR="${TARGET_START_DIR}/$(date '+%Y-%m-%d_%H:%M:%S')" # 目标目录,每次备份产生的以时间命名的目标目录TARGET_DIR都代表着当前的最新状态,但旧的、未曾改动的文件都是指向上一次备份的TARGET_DIR
readonly LATEST_LINK="${TARGET_START_DIR}/latest" # 基准目录
mkdir -p "${TARGET_START_DIR}" # 先把目标目录的起始目录创建好
rsync -av --delete \
"${SOURCE_DIR}/" \
--link-dest "${LATEST_LINK}" \
--exclude=".cache" \
"${TARGET_DIR}"
# 删除基准目录LATEST_LINK,然将最新一次备份ok的目标目录链接到LATEST_LINK作为下一次的基准目录;数据恢复时,只需要找到对应时间的目标目录即可,那里面每个目录里存放的就是对应时间节点的所有数据,无需按照传统的增量恢复->先恢复全量,再依次恢复每次增量一直到当前想要的时间节点
rm -rf "${LATEST_LINK}"
ln -s "${TARGET_DIR}" "${LATEST_LINK}"
注意:rsync所做的工作为镜像,保证远端服务器与本地文件的统一。如果本地文件没问题,远端也不会有问题。但如果本地文件发生误删或因程序运行错误,导致文件出问题,而在同步之前又没有意识到的话,远端的备份也就被损坏了。误删是比较容易发现的,可以及时矫正。但程序运行出问题,则不好判断了。因此,还需要其他判断机制辅助;使用 rsync 在远程传输数据(备份数据)前,是需要进行登陆认证的,这个过程需要借助 ssh 协议或者 rsync 协议才能完成。在 rsync 命令中,如果使用单个冒号(:),则默认使用 ssh 协议;反之,如果使用两个冒号(::),则使用 rsync 协议。区别在于,rsync 协议在使用时需要额外配置,增加了工作量,但优势是更加安全;反之,ssh 协议使用方便,无需进行配置,但有泄漏服务器密码的风险。
rpm -qa rsync
yum install rsync xinetd #xinetd是新一代的网络守护进程服务程序,又叫超级Internet服务器,常用来管理多种轻量级Internet服务。Xinetd提供类似于inetd+tcp_wrapper的功能
#服务端添加配置文件rsyncd.conf
vi /etc/rsyncd.conf
#以下是全局配置
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/lock/rsyncd
[zentaobak] #模块名,在源服务器指定这个名字
comment = sync rsync/home #描述信息
path = /home/DB_bak #备份目录
use chroot=yes #使用chroot,用root权限
read only = no #设置本地备份目录为读写权限
uid=root
gid=root
max connections=10 #客户端最大连接数
auth users = root #指定数据同步用户
secrets file = /etc/rsyncd.pass #指定数据同步用户信息文件
hosts allow=10.251.132.36 #允许连接的客户端
ignore errors = yes #忽略出现I/O错误
timeout = 600
vi /etc/rsyncd.pass #创建认证文件,格式是用户名:密码;如下
root:glong@123
chmod 600 /etc/rsyncd.pass
#修改/etc/xinetd.d/rsync文件,disable 改为 no
service rsync
{
disable = no
socket_type = stream
wait = no
user = root
server = /usr/bin/rsync
server_args = --daemon
log_on_failure += USERID
}
#启动服务端,rsync默认端口是873,防火墙要放开该端口
rsync --daemon --config=/etc/rsyncd.conf
sudo firewall-cmd --zone=public --add-port=873/tcp --permanent
sudo systemctl restart firewalld.service
chkconfig xinetd on
service xinetd start
#安装inotify-tools软件
wget http://cloud.github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
tar xf inotify-tools-3.14.tar.gz
./configure --prefix=/usr/local/inotify && make
make install
cd /usr/local/inotify/
echo "PATH=/usr/local/inotify/bin:$PATH" >>/etc/profile.d/inotify.sh
source /etc/profile.d/inotify.sh
echo "/usr/local/inotify/lib" >/etc/ld.so.conf.d/inotify.conf
ldconfig -v | grep inotify #验证库路径正确
/usr/local/inotify/lib:
libinotifytools.so.0 -> libinotifytools.so.0.4.1
ln -sv /usr/local/inotify/include/ /usr/include/inotify
#rsycn的客户端/文件发送端配置;客户端配置简单 只需要配置密码既可,只需要填写rsync服务的密码
vi /etc/rsync_client.pwd
glong@123 #同服务端密码文件中的密码
chmod 600 /etc/rsync_client.pwd
#同步测试:将本地/root/hello文件同步到 10.251.132.39远程服务器 DB_bak 目录下
rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd /root/hello root@10.251.132.39::DB_bak
缺点:当网络很繁忙,且文件变化比较频繁时,而且需要同步的rsync服务器端比较多时,rsync+inotify就满足不了需求了。可以使用rsync+sersync方案,可更快更节约资源实现数据同步,弥补rsync+inotify带来的不足,rsync+inotify还有一个重大的缺点就是数据传输只是单向的,当运维人员由于“粗心”把数据直接传输rsync服务器端时,inotify主机是得不到rsync服务器端的数据,于是unison+inotify实现web数据双向同步,解决了rsync+inotify的这一缺点。
2.2 可识别备份数据差异的方式同步
rdiff-backup工具:它不只可以做增量备份,而且会保留每次备份的状态,可识别新备份和上一次备份的差别,可轻松回滚到之前的某个版本。但是要求本地服务器和远端服务器需要安装统一版本的rdiff-backup。另外还有2款工具 duplicity和`Rsnapshot也可以做类似工作。
sudo apt-get install python-dev librsync-dev
wget -C https://sourceforge.net/projects/librsync/files/latest/download/ibrsync-0.9.7.tar.gz
tar xvzf librsync-0.9.7.tar.gz
export CFLAGS="$CFLAGS -fPIC"
./configure --prefix=/home/user/rsync --with-pic
make
make install
python setup.py install --prefix=/home/user/rdiff-backup
python setup.py --librsync-dir=/home/user/rsync install -- prefix=/home/user/rdiff-backup
vi .bashrc 或.bash_profile #添加环境变量
export PATH=${PATH}:/home/user/rdiff-backup/bin
export PYTHONPATH=${PYTHONPATH}:/home/user/rdiff-backup/lib/python2.x/site-packages
ssh user@host 'echo ${PATH}' #验证变量
rdiff-backup --no-compression --print-statistics user@host::/home/user/source_dir destination_dir # --force参数可覆盖没目标已存在的文件,--exclude 和--include 指定排除和包含某目录
#将上述备份命令加入计划任务
crontab -e
5 22 */1 * * 备份命令 #每天22点05分执行
#还原
rdiff-backup -r now destination_dir user@host::/home/user/source_dir.restore
#只还原10天前的
rdiff-backup -r 10D destination_dir user@host::/home/user/source_dir.restore
#从增量文件中恢复还原,增量文件位置: destination_dir/rdiff-backup-data/increments/server_add.2014-02-21T09:22:45+08:00.missing
rdiff-backup destination_dir/rdiff-backup-data/increments/server_add.2014-02-21T09:22:45+08:00.missing user@host::/home/user/source_dir.restore/server_add
#删除2周前的备份,注意,一年中一直未更改的现有文件仍将保留。但15天前的文件将会删除,在此命令后无法恢复,使用 --force会同时删除多个增量文件,而使用--remove-older-than不会
rdiff-backup --remove-older-than 2W --force destination_dir
rdiff-backup --list-increments destination_dir/
#查看5天内的增量文件
rdiff-backup --list-changed-since 5D destination_dir/.
#源和目标文件的差异比对
rdiff-backup --compare user@host::source-dir destination_dir
#2周前那个时间点,源和目标文件的差异比对
rdiff-backup --compare-at-time 2W user@host::source-dir destination_dir
相关文献:
http://www.saltycrane.com/blog/2008/02/backup-on-linux-rsnapshot-vs-rdiff/
http://james.lab6.com/2008/07/09/rdiff-backup-and-duplicity/
http://bitflop.com/document/75
http://askubuntu.com/questions/2596/comparison-of-backup-tools
http://www.reddit.com/r/linux/comments/fgmbb/rdiffbackup_duplicity_or_rsnapshot_which_is/
http://serverfault.com/questions/491341/optimize-space-rdiff-backup
2.3 rsync+sersync方案
sersync是使用c++编写,而且对linux系统文件系统产生的临时文件和重复的文件操作进行过滤,所以在结合rsync同步的时候,节省了运行时耗和网络资源。因此更快。
sersync配置起来很简单,其中bin目录下已经有基本上静态编译的2进制文件,配合bin目录下的xml配置文件直接使用即可。
sersync使用多线程进行同步,尤其在同步较大文件时,能够保证多个服务器实时保持同步状态。
sersync有出错处理机制,通过失败队列对出错的文件重新同步,如果仍旧失败,则按设定时长对同步失败的文件重新同步。
sersync自带crontab功能,只需在xml配置文件中开启,即可按您的要求,隔一段时间整体同步一次。无需再额外配置crontab功能。
wget --no-check-certificate https://sersync.googlecode.com/files/sersync2.5_64bit_binary_stable_final.tar.gz
mkdir -pv /usr/local/sersync/{conf,bin,log}
tar xf sersync2.5_64bit_binary_stable_final.tar.gz
ls #如下
confxml.xml sersync2
mv confxml.xml /usr/local/sersync/conf/
mv sersync2 /usr/local/sersync/bin/
cd /usr/local/sersync/
echo "PATH=/usr/local/sersync/bin:$PATH" >>/etc/profile.d/sersync.sh
source /etc/profile.d/sersync.sh
echo "pwd123" >/usr/local/sersync/sersync.pwd
chmod 600 /usr/local/sersync/sersync.pwd
#修改sersync的配置文件
vim /usr/local/sersync/conf/confxml.xml #如下所示
<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
#设置本地的ip地址和监听的端口
<host hostip="172.16.22.3" port="8008"></host>
#debug模式是否开启
<debug start="false"/>
#xfs文件系统是否开启
<fileSystem xfs="false"/>
#同步时,是否支持正则表达式,默认关闭
<filter start="false">
<exclude expression="(.*)\.svn"></exclude>
<exclude expression="(.*)\.gz"></exclude>
<exclude expression="^info/*"></exclude>
<exclude expression="^static/*"></exclude>
</filter>
# 设置要监控的事件
<inotify>
<delete start="true"/>
<createFolder start="true"/>
<createFile start="false"/>
<closeWrite start="true"/>
<moveFrom start="true"/>
<moveTo start="true"/>
<attrib start="false"/>
<modify start="false"/>
</inotify>
#同步的设置
<sersync>
#同步的路径,本地的目录
<localpath watch="/website">
#rsync服务器的ip地址和rsync配置文件里面定义的模块
<remote ip="172.16.22.1" name="htdocs"/>
#<!-- -->括起来表示注释
<!--<remote ip="192.168.8.39" name="tongbu"/>-->
<!--<remote ip="192.168.8.40" name="tongbu"/>-->
</localpath>
<rsync>
#rsync指令参数
<commonParams params="-artuz"/>
#rsync同步认证设置的内容,user指定用户名,password指定存放密码的文件路径
<auth start="true" users="backuper" passwordfile="/usr/local/sersync/sersync.pwd"/>
#设置rsync远程服务端口
<userDefinedPort start="false" port="874"/><!-- port=874 -->
#设置超时时间
<timeout start="true" time="100"/><!-- timeout=100 -->
#设置ssh加密传输模式,默认关闭
<ssh start="false"/>
</rsync>
#设置sersync传输失败日志脚本路径
<failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
#设置rsync+crontab定时传输,默认关闭
<crontab start="false" schedule="600"><!--600mins-->
<crontabfilter start="false">
<exclude expression="*.php"></exclude>
<exclude expression=\'#\'" /*"></exclude>
</crontabfilter>
</crontab>
#设置sersync传输后调用name指定的插件脚本,默认关闭
<plugin start="false" name="command"/>
</sersync>
#插件脚本范例
<plugin name="command">
<param prefix="/bin/sh" suffix="" ignoreError="true"/> <!--prefix /opt/tongbu/mmm.sh suffix-->
<filter start="false">
<include expression="(.*)\.php"/>
<include expression="(.*)\.sh"/>
</filter>
</plugin>
</head>
#sersync客户端侧,开启同步机制,进行监控
sersync2 -r -d &
2.4 unison+inotify实现数据双向同步
Unison是一款跨平台的文件同步对象,不仅支撑本地对本地同步,也支撑经由过程SSH、RSH和Socket等收集和谈进行同步。Unison支撑双向同步操纵,你既可以从A同步到B,也可以从B同步到A,这些都不须要额外的设定。
#两端服务器都安装如下3个包
wget ftp://distro.ibiblio.org/slitaz/sources/packages-2.0/o/ocaml-3.10.2.tar.gz
wget http://freebsd.ntu.edu.tw/FreeBSD/ports/distfiles/unison-2.32.52/unison-2.32.52.tar.gz
wget http://cloud.github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
#解压缩
tar xf inotify-tools-3.14.tar.gz
tar xf ocaml-3.10.2.tar.gz
tar xf unison-2.32.52.tar.gz
#编译安装inotify,也可以yum install -y inotify-tools
cd inotify-tools-3.14
./configure --prefix=/usr/local/inotify && make && make install
cd /usr/local/inotify/ #同上
echo "PATH=/usr/local/inotify/bin:$PATH" >/etc/profile.d/inotify.sh
source /etc/profile.d/inotify.sh
echo "/usr/local/inotify/lib" >/etc/ld.so.conf.d/inotify.conf
ldconfig -v | grep inotify
ln -sv /usr/local/inotify/include/ /usr/include/inotify
#编译安装ocaml,unison依赖于ocaml
cd /root/ocaml-3.10.2
./configure
make world opt
make install
cd /root/unison-2.32.52
yum -y install ctags-etags #安装依赖
make UISTYLE=text
make install
cp unison /usr/local/bin
#配置服务器间ssh密钥信任
ssh-keygen -t rsa #生成ssh的密钥对,同理完成后,服务器B生成的公钥也传到服务器A上
scp ~/.ssh/id_rsa.pub 172.16.22.3:/root
mv id_rsa.pub .ssh/authorized_keys #在服务器B上把服务器A传来的公钥文件改名并存放到ssh目录下
chmod 600 .ssh/authorized_keys #给公钥文件改权限为600
service sshd restart
2.5 syncthing 工具
它是一款开源免费的数据同步工具,基于P2P的跨平台文件同步工具,通过tcp建立设备连接,再通过TLS进行数据安全传输,支持公网与局域网搭建、支持单双向同步与历史版本控制–“后悔药”(备份机未感染情况下,历史版本理论上可以防止勒索病毒的,暂无实战相关资料佐认)、支持Android、Linux、Windows、Mac等系统,且服务器资源占用小。该软件安装需要源服务器与备份服务器都开启8384 、22000 端口;
官方文档:https://docs.syncthing.net/
端口说明:
8384 (TCP)是Web访问控制端口
22000 (TCP) 是节点访问端口
21027 (UDP) 关于本地发现的端口
44647 (UDP)
37269 (UDP)
firewall-cmd --permanent --add-port=8384/tcp --zone=public
firewall-cmd --permanent --add-port=22000/tcp --zone=public
#开启防火墙21027、44647、37269 udp端口
firewall-cmd --zone=public --add-port=21027/udp --permanent
firewall-cmd --zone=public --add-port=44647/udp --permanent
firewall-cmd --zone=public --add-port=37269/udp --permanent
#重启防火墙
firewall-cmd --reload
systemctl status firewalld
#syncthing安装
mkdir ./syncthing
cd ./syncthingwget https://github.com/syncthing/syncthing/releases/download/v1.16.1/syncthing-linux-amd64-v1.16.1.tar.gz
tar -zxvf syncthing-linux-amd64-v1.16.1.tar.gz
cd ./syncthing-linux-amd64-v1.16.1
#服务启动,ctrl + c 停止运行syncthing
/syncthing
#源服务器与备份服务器上均修改syncthing配置文件,默认存放路径 /root/.config/syncthing/
vi /root/.config/syncthing/config.xml #修改syncthing配置文件放开ip访问限制,syncthing默认仅支持本机访问web管理端;将127.0.0.1:8384 改成 [指定ip]:8384 或 0.0.0.0:8384
#完成后期待项目
nohup syncthing &> /dev/null &
#配置自启动
mv /root/syncthing/syncthing-linux-amd64-v1.16.1/etc/linux-systemd/system/syncthing@.service syncthing@root.service #syncthing自带有syncthing@.service文件,修改为syncthing@root.service
cp /root/syncthing/syncthing-linux-amd64-v1.16.1/etc/linux-systemd/system/syncthing@root.service /etc/systemd/system/
vi /etc/systemd/system/syncthing@root.service #修改ExecStart=/usr/bin/syncthing serve --no-browser --no-restart --logflags=0为
ExecStart= /root/syncthing/syncthing-linux-amd64-v1.16.1/syncthing serve --no-browser --no-restart --logflags=0
systemctl daemon-reload
systemctl enable /etc/systemd/system/syncthing@root.service
完成上述配置后,在浏览器输入 http://服务器IP:8384 进行管理端访问,初入web控制端界面如下:
web管理端默认是不做身份验证的,因此会弹出安全提示框,接下来为web管理端备注设备名、配置用户名/密码、配置局域网本地访问模式。
更多详情参看linux间文件实时同步(syncthing) 。
2.6 异地备份
2.7、Duplicity 备份工具
duplicity是一款开源的备份工具,支持去重,通过生成加密的 tar 格式卷并可上传到远程或者本地文件服务器。该项目使用 librsync 实现增量的归档,因此对空间占用是非常高效的。它使用 GnuPG 来加密和签名归档。因此无需担心被服务器上修改。duplicity能将数据轻松的备份到本地、共享存储和云存储等。alicloud-duplicity就是基于duplicity、支持OSS存储的开源备份工具,alicloud-duplicity支持duplicity的所有命令和参数。另Duplicity 还包含了 rdiffdir 工具用来比较两个目录的差异。
三、附录:备份脚本
1)mysql备份脚本示例:
#!/bin/bash
#Name:backmysql.sh
#This is a shell script for auto DB backup and delete old backup
backupdir=/bak/mysqlbak
time=` date +%Y%m%d%H `
mysql_bin_dir/mysqldump -u root -ppwd database | gzip > $backupdir/database$time.sql.gz
# 格式要求:-exec 要执行的命令 空格{}空格\;
find $backupdir -name "databasename_*.sql.gz" -type f -mtime +7 -exec rm {} \ ; > /dev/null 2>&1
转载:bakmysql.sh;
2)rdiff-backup差异备份脚本
#!/bin/bash
export PYTHONPATH=${PYTHONPATH}:/soft/rdiff_backup/lib/python2.7/site-packages/
rdiff-backup --no-compression -v5 --exclude '**trash' user@server::source/ bak_dir/
ret=$?
if test $ret -ne 0; then
echo "Wrong in bak"| mutt -s"Wrong in bak"bak@mail.com
else
echo "Right in bak"| mutt -s"Right in bak"bak@mail.com
fi
echo "Finish rdiff-backup $0 ---`date`---">>bak.log 2>&1
echo "`rdiff-backup --exclude '**trash' --compare-at-time 1D user@server::source/ bak_dir/`"| mutt -s"Lists of baked files"bak@mail.com
3)Rsync示例脚本
#!/bin/sh
#备份目录
BACK_HOME="/opt/zbox/app/zentaopro/tmp/backup"
newfile=“aa”
#获取最新文件夹名
code_newfile=ls -t $BACK_HOME/*code.zip.php | head -1
file_newfile=ls -t $BACK_HOME/*file.zip.php | head -1
sql_newfile=ls -t $BACK_HOME/*sql.php | head -1
#将最新文件夹下的包远程到服务端取
rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd $code_newfile root@dest_ip::DB_bak
rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd $file_newfile root@dest_ip1::DB_bak
rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd $sql_newfile root@dest_ip2::DB_bak
#备份目录
BACK_HOME="/mnt/main_back/DB_bak"
#SVN备份目录
SVN_BACK_HOME="/mnt/main_back/svn_bak"
#删除7天前备份的所有文件(包括文件夹)
find /mnt/main_back/DB_bak/* -mtime +7 -exec rm -rf {} ;
find /mnt/main_back/svn_bak/* -mtime +7 -exec rm -rf {} ;
4)rsync+inoticy示例脚本
!/bin/bash
host=172.16.22.1
src=/website
des=htdocs
inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e modify,delete,create,attrib $src \
| while read files
do
/usr/bin/rsync -vzrtopg --progress --password-file=/etc/rsyncd.secrets $src backuper@$host::$des
echo "${files} was rsynced" >>/tmp/rsync.log 2>&1
done
5)unison同步示例脚本
#####################################################################
#服务器A的脚本
#####################################################################
#!/bin/bash
ipB="172.16.22.3"
srcA="/web/htdocs"
dstB="/website"
/usr/local/inotify/bin/inotifywait -mrq -e create,delete,modify,move $srcA | while read line; do
/usr/local/bin/unison -batch $srcA ssh://$ipB/$dstB
echo -n "$line " >> /var/log/inotify.log
echo `date | cut -d " " -f1-4` >> /var/log/inotify.log
done
##服务器B的脚本
vim serB.sh
#####################################################################
#/bin/bash
ipA="172.16.22.1"
srcB="/website"
dstA="/web/htdocs"
/usr/local/inotify/bin/inotifywait -mrq -e create,delete,modify,move $srcB | while read line; do
/usr/local/bin/unison -batch $srcB ssh://$ipA/$dstA
echo -n "$line " >> /var/log/inotify.log
echo `date | cut -d " " -f1-4` >> /var/log/inotify.log
done
四、灾备方案设计
4.1、灾备分析
4.2 灾备设计目标
这里借鉴于HP公司的经验,将整体目标的设计和实施分为5个阶段:
1)容灾项目立项开始
2)灾难风险分析
3)灾难恢复计划制定
4)方案实施
5)运营保障
4.3 灾备/恢复 体系总体设计
下表是各容灾方案的整体比较:
1)应用层容灾
2)数据库容灾
Activelog的备份方式:
用数据库功能实现远程数据复制的优点:
3)镜像软件容灾
4)磁盘阵列容灾
性能分析:
4.4 灾备恢复流程
4.5 灾备有效性测试
1)测试方法:
2)测试频率
3)变动因素:
4)测试流程制定