1 说在前面的话
rsync官方网站: https://www.samba.org/ftp/rsync/rsync.html
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同步基本说明
rsync的目的是实现本地主机和远程主机上的文件同步(包括本地推到远程,远程拉到本地两种同步方式),也可以实现本地不同路径下文件的同步,但不能实现远程路径1到远程路径2之间的同步(scp可以实现)。
不考虑rsync的实现细节,就文件同步而言,涉及了源文件和目标文件的概念,还涉及了以哪边文件为同步基准。例如,想让目标主机上的文件和本地文件保持同步,则是以本地文件为同步基准,将本地文件作为源文件推送到目标主机上。反之,如果想让本地主机上的文件和目标主机上的文件保持同步,则目标主机上的文件为同步基准,实现方式是将目标主机上的文件作为源文件拉取到本地。当然,要保持本地的两个文件相互同步,rsync也一样能实现,这就像Linux中cp命令一样,以本地某文件作为源,另一文件作为目标文件,但请注意,虽然rsync和cp能达到相同的目的,但它们的实现方式是不一样的。
既然是文件同步,在同步过程中必然会涉及到源和目标两文件之间版本控制的问题,例如是否要删除源主机上没有但目标上多出来的文件,目标文件比源文件更新(newer than source)时是否仍要保持同步,遇到软链接时是拷贝软链接本身还是拷贝软链接所指向的文件,目标文件已存在时是否要先对其做个备份等等。
rsync同步过程中由两部分模式组成:决定哪些文件需要同步的检查模式以及文件同步时的同步模式。
(1).检查模式是指按照指定规则来检查哪些文件需要被同步,例如哪些文件是明确被排除不传输的。默认情况下,rsync使用"quick check"算法快速检查源文件和目标文件的大小、mtime(修改时间)是否一致,如果不一致则需要传输。当然,也可以通过在rsync命令行中指定某些选项来改变quick check的检查模式,比如"--size-only"选项表示"quick check"将仅检查文件大小不同的文件作为待传输文件。rsync支持非常多的选项,其中检查模式的自定义性是非常有弹性的。
(2).同步模式是指在文件确定要被同步后,在同步过程发生之前要做哪些额外工作。例如上文所说的是否要先删除源主机上没有但目标主机上有的文件,是否要先备份已存在的目标文件,是否要追踪链接文件等额外操作。rsync也提供非常多的选项使得同步模式变得更具弹性。
相对来说,为rsync手动指定同步模式的选项更常见一些,只有在有特殊需求时才指定检查模式,因为大多数检查模式选项都可能会影响rsync的性能。
3.选项说明和示例
接下来是rsync的选项说明。
-v:显示rsync过程中详细信息。可以使用"-vvvv"获取更详细信息。
-P:显示文件传输的进度信息。(实际上"-P"="--partial --progress",其中的"--progress"才是显示进度信息的)。
-n --dry-run :仅测试传输,而不实际传输。常和"-vvvv"配合使用来查看rsync是如何工作的。
-a --archive :归档模式,表示递归传输并保持文件属性。等同于"-rtopgDl"。
-r --recursive:递归到目录中去。
-t --times:保持mtime属性。强烈建议任何时候都加上"-t",否则目标文件mtime会设置为系统时间,导致下次更新
:检查出mtime不同从而导致增量传输无效。
-o --owner:保持owner属性(属主)。
-g --group:保持group属性(属组)。
-p --perms:保持perms属性(权限,不包括特殊权限)。
-D :是"--device --specials"选项的组合,即也拷贝设备文件和特殊文件。
-l --links:如果文件是软链接文件,则拷贝软链接本身而非软链接所指向的对象。
-z :传输时进行压缩提高效率。
-R --relative:使用相对路径。意味着将命令行中指定的全路径而非路径最尾部的文件名发送给服务端,包括它们的属性。用法见下文示例。
--size-only :默认算法是检查文件大小和mtime不同的文件,使用此选项将只检查文件大小。
-u --update :仅在源mtime比目标已存在文件的mtime新时才拷贝。注意,该选项是接收端判断的,不会影响删除行为。
-d --dirs :以不递归的方式拷贝目录本身。默认递归时,如果源为"dir1/file1",则不会拷贝dir1目录,使用该选项将拷贝dir1但不拷贝file1。
--max-size :限制rsync传输的最大文件大小。可以使用单位后缀,还可以是一个小数值(例如:"--max-size=1.5m")
--min-size :限制rsync传输的最小文件大小。这可以用于禁止传输小文件或那些垃圾文件。
--exclude :指定排除规则来排除不需要传输的文件。
--delete :以SRC为主,对DEST进行同步。多则删之,少则补之。注意"--delete"是在接收端执行的,所以它是在
:exclude/include规则生效之后才执行的。
-b --backup :对目标上已存在的文件做一个备份,备份的文件名后默认使用"~"做后缀。
--backup-dir:指定备份文件的保存路径。不指定时默认和待备份文件保存在同一目录下。
-e :指定所要使用的远程shell程序,默认为ssh。
--port :连接daemon时使用的端口号,默认为873端口。
--password-file:daemon模式时的密码文件,可以从中读取密码实现非交互式。注意,这不是远程shell认证的密码,而是rsync模块认证的密码。
-W --whole-file:rsync将不再使用增量传输,而是全量传输。在网络带宽高于磁盘带宽时,该选项比增量传输更高效。
--existing :要求只更新目标端已存在的文件,目标端还不存在的文件不传输。注意,使用相对路径时如果上层目录不存在也不会传输。
--ignore-existing:要求只更新目标端不存在的文件。和"--existing"结合使用有特殊功能,见下文示例。
--remove-source-files:要求删除源端已经成功传输的文件。
--list-only:该选项强制rsync仅列出源路径的文件列表而不是进行文件传输。如果rsync命令行中只给出了一个地址,将隐含该选项。注意通配符会被shell解析并扩展为rsync的参数
4.daemon配置文件rsyncd.conf
默认"rsync --daemon"读取的配置文件为/etc/rsyncd.conf,有些版本的系统上可能该文件默认不存在。rsyncd.conf的配置见man rsyncd.conf。以下是部分内容:
[root@xuexi ~]# cat /etc/rsyncd.conf
# /etc/rsyncd: configuration file for rsync daemon mode # See rsyncd.conf man page for more options. # configuration example: # uid = nobody
# gid = nobody
# use chroot = yes
# max connections = 4
# pid file = /var/run/rsyncd.pid
# exclude = lost+found/
# transfer logging = yes
# timeout = 900
# ignore nonreadable = yes
# dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 # [ftp1]
# path = /home/ftp
# comment = ftp export area
在上述示例配置文件中,先定义了一些全局选项,然后定义了[ftp1],这个用中括号包围的"[ftp1]"就是rsync中所谓的模块,ftp1为模块ID,必须保证唯一,每个模块中必须定义一项"path",path定义的是该模块代表的路径,例如此示例文件中,如果想请求ftp1模块,则在客户端使用"rsync user@host::ftp1",这表示访问user@host上的/home/ftp目录,如果要访问/home/ftp目录下的子目录www,则"rsync user@host::ftp1/www"。
以下是常见的配置项,也算是一个配置示例:
######### 全局配置参数 ##########
port=888 # 指定rsync端口。默认873
uid = rsync # rsync服务的运行用户,默认是nobody,文件传输成功后属主将是这个uid
gid = rsync # rsync服务的运行组,默认是nobody,文件传输成功后属组将是这个gid
use chroot = no # rsync daemon在传输前是否切换到指定的path目录下,并将其监禁在内
max connections = 200 # 指定最大连接数量,0表示没有限制
timeout = 300 # 确保rsync服务器不会永远等待一个崩溃的客户端,0表示永远等待
motd file = /var/rsyncd/rsync.motd # 客户端连接过来显示的消息
pid file = /var/run/rsyncd.pid # 指定rsync daemon的pid文件
lock file = /var/run/rsync.lock # 指定锁文件
log file = /var/log/rsyncd.log # 指定rsync的日志文件,而不把日志发送给syslog
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 # 指定哪些文件不用进行压缩传输 ###########下面指定模块,并设定模块配置参数,可以创建多个模块###########
[longshuai] # 模块ID
path = /longshuai/ # 指定该模块的路径,该参数必须指定。启动rsync服务前该目录必须存在。rsync请求访问模块本质就是访问该路径。
ignore errors # 忽略某些IO错误信息
read only = false # 指定该模块是否可读写,即能否上传文件,false表示可读写,true表示可读不可写。所有模块默认不可上传
write only = false # 指定该模式是否支持下载,设置为true表示客户端不能下载。所有模块默认可下载
list = false # 客户端请求显示模块列表时,该模块是否显示出来,设置为false则该模块为隐藏模块。默认true
hosts allow = 10.0.0.0/24 # 指定允许连接到该模块的机器,多个ip用空格隔开或者设置区间
hosts deny = 0.0.0.0/32 # 指定不允许连接到该模块的机器
auth users = rsync_backup # 指定连接到该模块的用户列表,只有列表里的用户才能连接到模块,用户名和对应密码保存在secrts file中,
# 这里使用的不是系统用户,而是虚拟用户。不设置时,默认所有用户都能连接,但使用的是匿名连接
secrets file = /etc/rsyncd.passwd # 保存auth users用户列表的用户名和密码,每行包含一个username:passwd。由于"strict modes"
# 默认为true,所以此文件要求非rsync daemon用户不可读写。只有启用了auth users该选项才有效。
[xiaofang] # 以下定义的是第二个模块
path=/xiaofang/
read only = false
ignore errors
comment = anyone can access
注意:
(1).客户端推到服务端时,文件的属主和属组是配置文件中指定的uid和gid。但是客户端从服务端拉的时候,文件的属主和属组是客户端正在操作rsync的用户身份,因为执行rsync程序的用户为当前用户。
(2).auth users和secrets file这两行不是一定需要的,省略它们时将默认使用匿名连接。但是如果使用了它们,则secrets file的权限必须是600。客户端的密码文件也必须是600。
(3).关于secrets file的权限,实际上并非一定是600,只要满足除了运行rsync daemon的用户可读即可。是否检查权限的设定是通过选项strict mode设置的,如果设置为false,则无需关注文件的权限。但默认是yes,即需要设置权限。
5.配置实例:
一、服务器不开启daemon进程,客户端如何同步信息
1.服务端添加一个匿名模块
[anonymity]
path=/var/anonymity
comment=anonymuty_write
read only=no
ignore errors
2.rsync --list-only -e "ssh -l root" 192.168.9.7::anonymity /var/anonymity/ # 客户端使用ssh建立连接,如果后边没有跟本地目录,则会将目标服务器的文件显示在屏幕
二、服务器开启daemon进程,客户端同步信息
1.配置模块
[xuan]
path=/var/rsync # 设置路径
comment=rsync_xuan # 解释信息
read only=yes # 只读
auth users = xuan # 认证的用户名
secrets file = /etc/rsync.passwd # 存放密码的文件
2.创建模块中secrets file指定的密码文件
vim /etc/rsync.passwd
xuan:pwd123 # pwd123是密码
3./etc/rsync.passwd的权限设置为600,这步必须有
chmod 600 /etc/rsync.passwd
4.客户端进行连接
rsync --port 9205 xuan@192.168.9.7::xuan
6.inotify+rsync
1.安装inotify-tools
inotify由inotify-tools包提供。在安装inotify-tools之前,请确保内核版本高于2.6.13,且在/proc/sys/fs/inotify目录下有以下三项,这表示系统支持inotify监控,关于这3项的意义,下文会简单解释。
[root@node1 tmp]# ll /proc/sys/fs/inotify/
total 0
-rw-r--r-- 1 root root 0 Feb 11 19:57 max_queued_events
-rw-r--r-- 1 root root 0 Feb 11 19:57 max_user_instances
-rw-r--r-- 1 root root 0 Feb 11 19:57 max_user_watches
epel源上提供了inotify-tools工具,或者下载源码包格式进行编译。
inotify-tools源码包地址:http://www.p-pp.cn/app/rsync/inotify-tools-3.14.tar.gz
[root@localhost inotify-tools-3.14]# inotifywait -mrq -e modify,create,move,delete /var/www/html/
-m:持续监控
-r:递归整个目录
-q:简化输出信息
2.inotify+rsync示例脚本
#!/bin/bash
INOTIFY_CMD="inotifywait -mrq -e modify,create,move,delete /var/www/html"
RSYNC_CMD="rsync -avzH --delete --password-file=/etc/server.pass /var/www/html/ backuper@192.168.4.200::wwwroot"
$INOTIFY_CMD | while read DIRECTORY EVENT FILE
do
$RSYNC_CMD
done