1.rsync概述
rsync 是可以实现增量备份的工具。配合任务计划,rsync 能实现定时或间隔同步,配合 inotify 或 sersync,可以实现触发式的实时同步。
rsync 可以实现 scp 的远程拷贝(rsync 不支持远程到远程的拷贝,但 scp 支持)、cp 的本地拷贝、rm 删除和”ls -l”显示文件列表等功能。但需要注意的是,rsync 的最终目的或者说其原始目的是实现两端主机的文件同步,因此实现的 scp/cp/rm 等功能仅仅只是同步的辅助手段,且 rsync 实现这些功能的方式和这些命令是不一样的。事实上,rsync 有一套自己的算法,其算法原理以及 rsync 对算法实现的机制可能比想象中要复杂一些。平时使用 rsync 实现简单的备份、同步等功能足以,没有多大必要去深究这些原理性的内容。但是想要看懂 rsync 命令的 man 文档、使用”-vvvv”分析 rsync 执行过程,以及实现 rsync 更强大更完整的功能,没有这些理论知识的支持是绝对不可能实现的。本篇文章将简单介绍 rsync 的使用方法和它常用的功能。在本篇文章之后的下几篇文章中,将介绍 inotify+rsync 和 sersync,再之后将详细解释 rsync 相关的原理,其中包括官方技术报告的翻译(即算法原理)、rsync 同步的整个过程(也是官方推荐文章的翻译),然后专门使用一篇文章通过示例来详细解释 rsync 算法原理,最后给出 rsync 的 man 文档翻译。希望各位朋友能藉此深入 rsync
2.rsync应用场景
3.rsync工作模式
本地模式: rsync类似于 cp命令
远程模式(ssh隧道模式)
rsync守护进程模式(rsync服务)
-v--verbose:详细模式输出 -q --quiet:精简输出模式 -c --checksum:打开校验开关,强制对文件传输进行校验 -a --archive:归档模式,表示以递归方式传输文件,并保持所有文件属性,等于-rlptgoD -r --recursive:对子目录以递归模式处理 -R --relative:使用相对路径信息 -b --backup:创建备份,也就是对于目的已经存在有同样的文件名时,将老的文件重新命名为~filename。 可以使用--suffix选项来指定不同的备份文件前缀。 --backup-dir:将备份文件(如~filename)存放在在目录下。 -suffix=SUFFIX:定义备份文件前缀 -u --update:仅仅进行更新,也就是跳过所有已经存在于DST,并且文件时间晚于要备份的文件。(不覆盖更新的文件) -l --links:保留软链结 -L --copy-links:想对待常规文件一样处理软链结 --copy-unsafe-links:仅仅拷贝指向SRC路径目录树以外的链结 --safe-links:忽略指向SRC路径目录树以外的链结 -H --hard-links:保留硬链结 -p --perms:保持文件权限 -o --owner:保持文件属主信息 -g --group:保持文件属组信息 -D --devices:保持设备文件信息 -t --times:保持文件时间信息 -S --sparse:对稀疏文件进行特殊处理以节省DST的空间 -n --dry-run:现实哪些文件将被传输 -W --whole-file:拷贝文件,不进行增量检测 -x --one-file-system:不要跨越文件系统边界 -B --block-size=SIZE:检验算法使用的块尺寸,默认是700字节 -e --rsh=COMMAND:指定使用rsh、ssh方式进行数据同步 --rsync-path=PATH:指定远程服务器上的rsync命令所在路径信息 -C --cvs-exclude:使用和CVS一样的方法自动忽略文件,用来排除那些不希望传输的文件 --existing:仅仅更新那些已经存在于DST的文件,而不备份那些新创建的文件 --delete:删除那些DST中SRC没有的文件 --delete-excluded:同样删除接收端那些被该选项指定排除的文件 --delete-after:传输结束以后再删除 --ignore-errors:及时出现IO错误也进行删除 --max-delete=NUM:最多删除NUM个文件 --partial:保留那些因故没有完全传输的文件,以是加快随后的再次传输 --force:强制删除目录,即使不为空 --numeric-ids:不将数字的用户和组ID匹配为用户名和组名 --timeout=TIME:IP超时时间,单位为秒 -I --ignore-times:不跳过那些有同样的时间和长度的文件 --size-only:当决定是否要备份文件时,仅仅察看文件大小而不考虑文件时间 --modify-window=NUM:决定文件是否时间相同时使用的时间戳窗口,默认为0 -T --temp-dir=DIR:在DIR中创建临时文件 --compare-dest=DIR:同样比较DIR中的文件来决定是否需要备份 -P 等同于 --partial --progress:显示备份过程 -z --compress:对备份的文件在传输时进行压缩处理 --exclude=PATTERN:指定排除不需要传输的文件模式 --include=PATTERN:指定不排除而需要传输的文件模式 --exclude-from=FILE:排除FILE中指定模式的文件 --include-from=FILE:不排除FILE指定模式匹配的文件 --version:打印版本信息 --address:绑定到特定的地址 --config=FILE:指定其他的配置文件,不使用默认的rsyncd.conf文件 --port=PORT:指定其他的rsync服务端口 --blocking-io:对远程shell使用阻塞IO -stats:给出某些文件的传输状态 --progress:在传输时现实传输过程 --log-format=formAT:指定日志文件格式 --password-file=FILE:从FILE中得到密码 --bwlimit=KBPS:限制I/O带宽,KBytes per second -h --help:显示帮助信息
本地模式
安装
[root@backup-rsync ~]$ yum install -y rsync [root@backup-rsync ~]$ systemctl start rsyncd [root@backup-rsync ~]$ systemctl enable rsyncd
关闭防火墙和selinux
[root@backup-rsync ~]$ systemctl status firewalld.service [root@backup-rsync ~]$ getenforce Disabled
复制文件
[root@backup-rsync ~]$ rsync dmxsp.sh /tmp/ [root@backup-rsync ~]$ rsync -a dmxsp.sh /tmp/ [root@backup-rsync ~]$ rsync -av dmxsp.sh /tmp/ 显示过程 sending incremental file list sent 54 bytes received 12 bytes 132.00 bytes/sec total size is 28 speedup is 0.42
传输的时候,压缩数据
[root@backup-rsync ~]$ rsync -avz dmxsp.sh /tmp/
/tmp /tmp/ 不同的
/tmp:表示目录及目录下面的内容
/tmp/:表示目录下面的内容
远程模式(ssh隧道模式)
两台机器
172.16.1.116 172.16.1.16
push推文件172.16.1.116往172.16.1.16推
[root@backup-rsync ~]$ rsync -a /root/ 172.16.1.16:/tmp/
pull拉文件172.16.1.116往172.16.1.16拉
[root@backup-rsync ~]$ rsync -av 172.16.1.116:/root/php.zip /tmp/
rsync服务模式(守护进程模式)
检查软件是否安装
backup-rsync(服务的)nfs(客户端)
[root@backup-rsync ~]$ rpm -qa | grep rsync rsync-3.1.2-11.el7_9.x86_64 [root@nfs ~]$ rpm -qa | grep rsync rsync-3.1.2-10.el7.x86_64
服务端
配置文件
[root@backup-rsync ~]$ cat /etc/rsyncd.conf
创建rsync用户(是根据修改的配置文件来创建的,是可以随便创建用户的)
[root@backup-rsync ~]$ useradd -s /sbin/nologin -M rsync [root@backup-rsync ~]$ id rsync uid=1001(rsync) gid=1001(rsync) groups=1001(rsync)
密码文件 用户名:密码
[root@backup-rsync ~]$ vim /etc/rsync.passwd [root@backup-rsync ~]$cat -A /etc/rsync.passwd rsync_backup:1$ [root@backup-rsync ~]$ cat /etc/rsync.passwd rsync_backup:1
修改目录权限(密码文件不想给其它用户看)
[root@backup-rsync ~]$ ll /etc/rsync.passwd -rw-r--r-- 1 root root 15 Jul 5 18:12 /etc/rsync.passwd [root@backup-rsync ~]$ chmod 600 /etc/rsync.passwd [root@backup-rsync ~]$ ll /etc/rsync.passwd -rw------- 1 root root 15 Jul 5 18:12 /etc/rsync.passwd
目录(共享目录)
[root@backup-rsync ~]$ mkdir -p /backup [root@backup-rsync ~]$ chown -R rsync.rsync /backup/ [root@backup-rsync ~]$ ll -d /backup/ drwxr-xr-x 2 rsync rsync 6 Jul 5 18:21 /backup/
修改配置文件
[root@backup-rsync ~]$ cat -A /etc/rsyncd.conf uid = rsync$ gid = rsync$ port = 873$ fake super = yes$ use chroot = no$ max connections = 200$ timeout = 600$ ignore errors$ read only = false$ list = false$ auth users = rsync_backup$ secrets file = /etc/rsync.passwd$ log file = /var/log/rsyncd.log$ pid file = /var/run/rsyncd.pid hosts allow = 172.16.1.0/24 #####################################$ [backup]$ comment = welcome to oldboyedu backup!$ path = /backup$
[root@backup-rsync ~]$ cat /etc/rsyncd.conf uid = rsync gid = rsync port = 873 fake super = yes use chroot = no max connections = 200 timeout = 600 ignore errors read only = false list = false auth users = rsync_backup secrets file = /etc/rsync.passwd log file = /var/log/rsyncd.log pid file = /var/run/rsyncd.pid hosts allow = 172.16.1.0/24 ##################################### [backup] comment = welcome to oldboyedu backup! path = /backup
开启服务并检查端口进程
[root@backup-rsync ~]$ systemctl start rsyncd [root@backup-rsync ~]$ systemctl enable rsyncd [root@backup-rsync ~]$ ss -lntup |grep rsync [root@backup-rsync ~]$ ps aux | grep rsync
在本地进程同步测试
[root@backup-rsync ~]$ rsync -av /etc/hostname rsync_backup@172.16.1.116::backup
客户端
传输文件
[root@nfs ~]$ rsync -avz /etc/passwd rsync_backup@172.16.1.116::backup
解决每次需要输入密码问题
[root@nfs ~]$ vim /etc/rsync.passwd [root@nfs ~]$ cat /etc/rsync.passwd 1
修改文件权限
[root@nfs ~]$ chmod 600 /etc/rsync.passwd [root@nfs ~]$ ll /etc/rsync.passwd -rw------- 1 root root 2 Oct 2 22:31 /etc/rsync.passwd
测试
[root@nfs ~]$ rsync -avz /tmp/ rsync_backup@172.16.1.116::backup --password-file=/etc/rsync.passwd
rsync配置文件模块配置
授权某个ip
hosts allow = 10.0.0.41
授权某个网段
hosts allow = 172.16.1.0/24
忽略错误程序
ignore errors
4.rsync应用案例
目标
备份网站代码,网站服务配置,脚本,日志
备份完成,备份本地保留一份,备份服务器留一份
服务器本地(保留30天),备份服务器保留180天
步骤
打包备份:(与定时任务配合)
网站代码: /var/nginx/html
配置文件: /etc/ /var/spool/cron/
日志: 暂时不备份,通过ELK/EFK收集.
通过rsync传输备份到备份服务器(与定时任务配合)
准备二台机器
rsync服务端
[root@backup-rsync ~]$ hostname -I | awk '{print $2}' 172.16.1.116
rsync客户端
[root@nfs ~]$ hostname -I | awk '{print $2}' 172.16.1.16
环境准备
rsync服务端客户端配置
打包备份脚本
打包备份并传输到备份服务器
加上定时任务
rsync服务端客户端配置测试
客户端
[root@nfs ~]$ mkdir -p /all-backup [root@nfs ~]$ touch /all-backup/cs.txt [root@nfs ~]$ rsync -avPz /all-backup/ rsync_backup@172.16.1.116::backup --password-file=/etc/rsync.passwd
打包备份脚本
[root@nfs ~]$ mkdir -p /var/nginx/html [root@nfs ~]$ tar zcf /all-backup/code-$(date +%F_%H).tar.gz /var/nginx/html/ tar: Removing leading `/' from member names [root@nfs ~]$ tar zcf /all-backup/conf-$(date +%F_%H).tar.gz /var/nginx/html/ tar: Removing leading `/' from member names [root@nfs ~]$ ll /all-backup/ total 8 -rw-r--r-- 1 root root 120 Jul 6 12:03 code-2022-07-06_12.tar.gz -rw-r--r-- 1 root root 120 Jul 6 12:08 conf-2022-07-06_12.tar.gz -rw-r--r-- 1 root root 0 Jul 6 11:44 cs.txt
备份脚本
[root@nfs ~]$ mkdir -p /server/scripts [root@nfs ~]$cat /server/scripts/all-backup.sh #!/bin/bash TIME=$(date +%F_%H) #code tar zcf /all-backup/code-$TIME.tar.gz /var/nginx/html/ #conf tar zcf /all-backup/conf-$TIME.tar.gz /var/nginx/html/
测试脚本
[root@nfs ~]$ ll /all-backup/ total 0 [root@nfs ~]$ sh /server/scripts/all-backup.sh tar: Removing leading `/' from member names tar: Removing leading `/' from member names [root@nfs ~]$ ll /all-backup/ total 8 -rw-r--r-- 1 root root 120 Jul 6 12:18 code-2022-07-06_12.tar.gz -rw-r--r-- 1 root root 120 Jul 6 12:18 conf-2022-07-06_12.tar.gz
打包备份并传输到备份服务器
[root@nfs ~]$ rsync -avPz /all-backup/ rsync_backup@172.16.1.116::backup --password-file=/etc/rsync.passwd
续写备份脚本
[root@nfs ~]$ cat /server/scripts/all-backup.sh #!/bin/bash TIME=$(date +%F_%H) #code tar zcf /all-backup/code-$TIME.tar.gz /var/nginx/html/ #conf tar zcf /all-backup/conf-$TIME.tar.gz /var/nginx/html/ #push to backup server rsync -avPz /all-backup/ rsync_backup@172.16.1.116::backup --password-file=/etc/rsync.passwd
测试脚本
[root@nfs ~]$ sh /server/scripts/all-backup.sh
加上定时任务(测试每分钟)
[root@nfs ~]$ crontab -l #push to backup server * * * * * sh /server/scripts/all-backup.sh &>/dev/null
多台客户端备份传输到服务端时比较乱,加上IP地址就知道是那台机器了
修改脚本
[root@nfs ~]$ cat /server/scripts/all-backup.sh #!/bin/bash TIME=$(date +%F_%H) IP=$(hostname -I | cut -d ' ' -f2) #mkdir ip dir mkdir -p /all-backup/$IP #code tar zcf /all-backup/$IP/code-$TIME.tar.gz /var/nginx/html/ #conf tar zcf /all-backup/$IP/conf-$TIME.tar.gz /var/nginx/html/ #push to backup server rsync -avPz /all-backup/ rsync_backup@172.16.1.116::backup --password-file=/etc/rsync.passwd
测试
修改脚本(不用每次创建目录)
[root@nfs ~]$ cat /server/scripts/all-backup.sh #!/bin/bash TIME=$(date +%F_%H) IP=$(hostname -I | cut -d ' ' -f2) Path=/all-backup #mkdir ip dir mkdir -p /all-backup/$IP/ #mkdir ip dir #第一种判断 #[ -d /all-backup/ ] || mkdir -p /all-backup/$IP #第二种判断 #if [ ! -d "/all-backup/" ];then # mkdir -p /all-backup/$IP #fi #第三种判断 [ -d $Path ] || mkdir -p $Path/$IP #code tar zcf /all-backup/$IP/code-$TIME.tar.gz /var/nginx/html/ #conf tar zcf /all-backup/$IP/conf-$TIME.tar.gz /var/nginx/html/ #push to backup server rsync -avPz /all-backup/ rsync_backup@172.16.1.116::backup --password-file=/etc/rsync.passwd
另一个脚本
[root@nfs ~]$ cat /server/scripts/backup-conf.sh # /bin/basg IP='hostname -I | awk '{print $2}'' TIME='date +%F_%w' # mkdir ip mkdir -p /backup/$IP/ # backup tar zcf /backup/$IP/conf_$TIME.tar.gz /etc/ /var/spool/cron/crontabs find /bankup/ -type f -anme "*.tar.gz" | xargs md5sum >/backup/#IP/md5sum.txt # push backup rsync -az /backup/ rsync_backup@172.16.1.116::backup --password-file=/etc/rsync.passwd # del backup find /backup/ -type f -name "*.tar.gz" -mtime +7 | xargs rm -f
5.邮件发送
启动服务为postfix
配置文件 /etc/mail.rc
set bsdcompat set from=********@qq.com 发件人 set smtp=smtps://smtp.qq.com:465 发件的smtp地址 set smtp‐auth‐user=*********@qq.com 认证用户和发件人一致 set smtp-auth-password= 授权码 set smtp-auth=login 无需修改,直接添加 set ssl-verify=ignore 无需修改,直接添加 set nss-config-dir=/etc/pki/nssdb/ 无需修改,直接添加
服务端校验、以及邮件通知脚本
#!/usr/bin/bash #1.定义全局的变量 export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin #2.定义局部变量 Path=/backup Date=$(date +%F) #3.查看 flag 文件,并对该文件进行校验, 然后将校验的结果保存至 result_时间 find $Path/ ‐type f ‐name "flag_$Date"|xargs md5sum ‐c >$Path/result_${Date} #4.将校验的结果发送邮件给管理员 mail ‐s "Rsync Backup $Date" 123@qq.com <$Path/result_${Date} #5.删除超过 7 天的校验结果文件, 删除超过 180 天的备份数据文件 find $Path/ ‐type f ‐name "result*" ‐mtime +7|xargs rm ‐f find $Path/ ‐type d ‐mtime +180|xargs rm ‐rf