rsync实现数据备份

时间:2021-07-02 21:34:07

rsync实现数据备份

1.简介

rsync(remote synchronization)是一款开源的,快速的,多功能的,可实现全量和增量的的本地或远程数据同步备份的优秀工具。

2.功能

scp、cp、rm、增量备份

  • rsync通过'quick check'算法,它仅同步大小或者最后修改时间发生变化的文件或目录。也可以根据权限,属主等属性变化来同步,但需要指定参数。

3.特性

  1. 支持拷贝特殊文件。如链接文件,设备等
  2. 可以排除指定文件或目录,相当于tar打包中排除命令
  3. 同步时可以保持文件的属性不变(-p)
  4. 可以实现增量备份
  5. 可以使用rcp、rsh、ssh等方式来传输文件(rsync本身对传输不加密
  6. 可以通过socket传输文件或数据(服务器后客户端传输使用的端口是tcp873
  7. 支持匿名或认证的进程模式传输,可实现数据的安全备份

4.用法

4.1语法

  • Local:
    rsync [OPTION...] SRC... [DEST]
  • Access via remote shell:
    Pull: rsync [OPTION] USER@HOST:SRC... [DEST]
    rsync /etc/fstab root@10.1.1.210:/tmp
    Push: rsync [OPTION...] SRC... [USER@]HOST:DEST
  • Access via rsync daemon:
    Pull: rsync [OPTION] USER@HOST::SRC... [DEST]
    rsync [OPTION...]rsync://USER@HOST[:PORT]/SRC... [DEST]
    Push: rsync [OPTION...] SRC... [USER@]HOST::DEST
    rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST

4.2选项

选项 作用
-avz 归档,同步时保留属性并压缩
-a archive 归档,用语同步时保留文件属性
-v verbose 同步过程信息
-z compress 压缩
-r recursive 递归
-t time 时间戳
-o owner 属主
-p permissive 权限
-g group属组
-P process 同步进度信息
-D device 保留设备信息
-l link 符号链接
-e 远程shell(默认ssh)
--exclude 排除文件
--bwlimit 带宽限制

5.运用场景

5.1实现两台服务器之间的数据同步cron+rsync

  1. 配置rsyncd服务端
  • 创建配置文件 vim /etc/rsyncd.conf

    id = rsync   #客户端连接到服务端后服务端进程执行者
    gid = rsync   #执行组
    use chroot = no   #是否chroot
    max connections = 100
    timeout 300
    strict modes = yes
    pid file = /var/run/rsyncd.pid   #pid文件
    lock file = /var/run/rsyncd.lock #锁文件,保持文件一致性
    log file = /var/log/rsyncd.log   #日志文件
    
    [bak]     #模块名称
    path = /bakup   #备份目录
    comment = bakup file  #模块说明
    ignore errors   #忽略错误
    read only = no  #可写
    hosts allow = *  #允许
    hosts deny = 172.16.1.1  #拒绝
    list = false   #能否被列表
    auth users = ruser  #允许那些用户同步 
    secrets file = /etc/rsync.passwd  #用户帐号密码文件(权限必须是600)
  • 创建密码文件并修改权限
vim /etc/rsync.passwd
user:12345
chomod 600 /etc/rsync.passwd
  • 创建共享目录并授权
useradd -r rsync #增加系统用户
mkdir /bakup
chown -R rsync,rsync /bakup
  • 加入开机自动启动脚本
vim /etc/rc.local
rsync --daemon
  1. 配置rsync客户端
  • 配置密码文件
vim /etc/rsync.passwd
12345
  • 推送文件
方法一:rsync -avz /etc/hosts ruser@192.168.179.131::bak --password-file=/etc/rsync.passwd
方法二:rsync -avz /etc/hosts rsync://ruser@192.168.179.131/bakup --password-file=/etc/rsync.passwd
  • 将rsync写入shell脚本中,将脚本放到cron中定时运行

永久生效

date #查看时间
vi /etc/crontab  #进入该文件
分 时 * * * ./root/copy.sh #写入

临时生效

crontab -e
编辑:分 时 * * * bash /root/copy.sh
cat copy.sh

6.实现实时同步(Inotify)

6.1介绍

  • Inotify,它是在内核 2.6.13 版本中引入的一个新功能,它为用户态监视文件系统的变化提供了强大的支持,允许监控程序打开一个独立文件描述符,并针对事件集监控一个或者多个文件,例如打开、关闭、移动/重命名、删除、创建或者改变属性。

6.2安装

rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm 
yum install inotify-tools

6.3用法

  • 常见用法:inotifywait -mrq --format '%Xe %w%f' -e modify,create,delete,attrib /game/

    选项 作用
    -m monitor,持续监控目标文件/目录
    -r recursive,递归
    -q quiet,静默模式
    --formit %Xe event事件 %w目录 %f文件
    -e 监控事件

rsync实现数据备份

6.4脚本

0#/bin/bash 
/usr/bin/inotifywait -mrq --format '%w%f'-e create,close_write,delete /backup |while read file  #发生更改的文件列表都接收到file 然后循环,但有什么鬼用呢?下面的命令都没有引用这个$file 下面做的是全量rsync
do 
cd /backup && rsync -az --delete /backup/ rsync_backup@192.168.24.101::backup/--password-file=/etc/rsync.password 
done

执行脚本

chomd +x rsync.sh
./rsync.sh

优化版

0#!/bin/bash
src=/data/                           # 需要同步的源路径
des=data                             # 目标服务器上 rsync --daemon 发布的名称,rsync --daemon这里就不做介绍了,网上搜一下,比较简单。
rsync_passwd_file=/etc/rsyncd.passwd            # rsync验证的密码文件
ip1=192.168.0.18                 # 目标服务器1
ip2=192.168.0.19                 # 目标服务器2
user=root                            # rsync --daemon定义的验证用户名
cd ${src}                              # 此方法中,由于rsync同步的特性,这里必须要先cd到源目录,inotify再监听 ./ 才能rsync同步后目录结构一致,有兴趣的同学可以进行各种尝试观看其效果
/usr/local/bin/inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ./ | while read file         # 把监控到有发生更改的"文件路径列表"循环
do
        INO_EVENT=$(echo $file | awk '{print $1}')      # 把inotify输出切割 把事件类型部分赋值给INO_EVENT
        INO_FILE=$(echo $file | awk '{print $2}')       # 把inotify输出切割 把文件路径部分赋值给INO_FILE
        echo "-------------------------------$(date)------------------------------------"
        echo $file
        #增加、修改、写入完成、移动进事件
        #增、改放在同一个判断,因为他们都肯定是针对文件的操作,即使是新建目录,要同步的也只是一个空目录,不会影响速度。
        if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'MODIFY' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]]         # 判断事件类型
        then
                echo 'CREATE or MODIFY or CLOSE_WRITE or MOVED_TO'
                rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des} &&         # INO_FILE变量代表路径哦  -c校验文件内容
                rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip2}::${des}
                 #仔细看 上面的rsync同步命令 源是用了$(dirname ${INO_FILE})变量 即每次只针对性的同步发生改变的文件的目录(只同步目标文件的方法在生产环境的某些极端环境下会漏文件 现在可以在不漏文件下也有不错的速度 做到平衡) 然后用-R参数把源的目录结构递归到目标后面 保证目录结构一致性
        fi
        #删除、移动出事件
        if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
        then
                echo 'DELETE or MOVED_FROM'
                rsync -avzR --delete --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des} &&
                rsync -avzR --delete --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip2}::${des}
                #看rsync命令 如果直接同步已删除的路径${INO_FILE}会报no such or directory错误 所以这里同步的源是被删文件或目录的上一级路径,并加上--delete来删除目标上有而源中没有的文件,这里不能做到指定文件删除,如果删除的路径越靠近根,则同步的目录月多,同步删除的操作就越花时间。
        fi
        #修改属性事件 指 touch chgrp chmod chown等操作
        if [[ $INO_EVENT =~ 'ATTRIB' ]]
        then
                echo 'ATTRIB'
                if [ ! -d "$INO_FILE" ]                 # 如果修改属性的是目录 则不同步,因为同步目录会发生递归扫描,等此目录下的文件发生同步时,rsync会顺带更新此目录。
                then
                        rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des} &&            
                        rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip2}::${des}
                fi
        fi
done