1、前言
基于LAN或WAN的网络应用之间进行数据传输或者同步非常普遍,比如远程数据镜像、备份、复制、同步,数据下载、上传、共享等等。对此,最简单、直接的做法是对数据进行完全复制。然而,数据在网络上来回被复制多次后就会存在大量副本,很多情形下这些文件副本之间仅有很小的差异,很可能是从同一个文件版本演化而来。另一方面,如果对文件进行完全复制,在文件较大的情况下,会占用大量网络带宽,同步时间也会较长。目前,广域网WAN的带宽与访问延迟仍然是急需解决的问题,完全复制使得很多网络应用无法提供良好的服务质量。Rsync是类Unix下常见的一种数据同步算法,它仅传输差异数据,从而节省网络带宽并提高效率。
2、算法介绍
2.1 分块Checksum算法
首先,rsync会把目标端fileDst的文件平均切分成若干个小块,每块的默认大小为700个字节(最后一块会小于这个数),然后对每块计算两个checksum:一个是32位的rolling checksum,是弱checksum,其使用的算法是Mark Adler发明的adler-32算法。另一个是强checksum,128位的md5 hash算法。(adler-32算法不属于本文讨论的主要内容,有兴趣可参考http://rsync.samba.org/tech_report/node3.html)
adler-32作为快算法是用来鉴别文件块的不同,但是弱的adler32算法碰撞概率太高了,所以还要引入强的md5 checksum算法以保证两文件块是相同的。也就是说,弱的rolling checksum是用来区别不同,而强的md5 checksum是用来确认相同。
2.2 checksum查找算法
目标端会把fileDst的一个checksum列表传给源端,这个列表中的每一项包含三个属性:rolling checksum(32bits)、md5 checksume(128bits)、文件块编号。源端rsync接收到这个列表后,会对源端fileSrc做同样的checksum,然后和目标端fileDst的checksum做对比,通过比对就可以感知哪些文件做了变动。为获得O(1)时间复杂度的查找性能,同步源端fileSrc拿到目标端fileDst的checksum数组后,会把这个数据存到一个hash table中。
2.3 比对算法
(1)取fileSrc的第一个文件块(假设是512个长度),也就是从fileSrc的第1个字节到第512个字节,取出来后做rolling checksum计算。计算好的值到hash表中查。
(2)如果查到了,说明fileDst中有潜在相同的文件块,就再比较md5的checksum。因为rolling checksume只有32位,发生碰撞的概率非常大,于是还要算md5的128bits的checksum,这样一来发生碰撞的概率就可以忽略了。如果rolling checksum和md5 checksum都相同,这说明在fileDst中有相同的块,我们需要记下这一块在fileDst下的文件编号。
(3)如果fileSrc的rolling checksum 没有在hash table中找到,那就表明这一文件块不存在于目标端。总之,只要rolling checksum 或 md5 checksum 其中有一个在目标端的checksum hash表中找不到匹配项,那么就会触发算法对fileSrc的滚动计算动作。即算法会住后滑动 1个字节,取fileSrc中字节2-513的文件块要做checksum,重新执行第一步的流程。
(4)当源端的fileSrc完全做完一遍rolling checksum后,就可以找出源端fileSrc与目标端fileDst不相同的文件块了,也就是要同步到目标端的文件块。之后进行传输。
(5)算法的简要流程如下图所示:
3、安装配置
3.1 安装
下载rsync-3.0.4.tar.gz ,地址:http://rsync.samba.org/ftp/rsync/src/rsync-3.0.4.tar.gz
解压安装包,命令:tar –xvzf rsync-3.0.4.tar.gz 进入到rsync文件夹执行: cd rsync-3.0.4 ./configure --prefix=/usr/local/rsync make make install
3.2 配置
Rsync安装完成之后默认没有配置文件,需要自己创建。
3.2.1 创建一系列文件夹
mkdir /usr/local/rsync/logs mkdir /usr/local/rsync/etc mkdir /usr/local/rsync/run
3.2.2 添加配置文件
vim /usr/local/rsync/etc/rsyncd.conf 内容如下:
uid = root gid = root port = 873 use chroot = no hosts allow = 192.168.31.22 #hosts deny = 192.168.10.0/24 pid file = /usr/local/rsync/run/rsyncd.pid lock file = /usr/local/rsync/run/rsync.lock log file = /usr/local/rsync/logs/rsyncd.log ignore errors [rsynctest] path = /home/laizy/rsync/rsynctest auth users = root secrets file = /usr/local/rsync/rsyncd.pass read only = no
3.2.3 添加密码文件
vim /usr/local/rsync/rsyncd.pass 格式为——用户名:密码。示例:
root:123456
3.2.4 为密码文件赋予权限
chmod 600 /usr/local/rsync/rsyncd.pass
3.2.5 安全配置
只允许IP为192.168.31.21的主机连入rsync server:
iptables -A INPUT -p tcp -s ! 192.168.31.22 --dport 873 -j DROP
3.2.6 启动服务
rsync --daemon --config=/usr/local/rsync/etc/rsyncd.conf &
4、命令详细说明
–v、–verbose详细模式输出 –q、–quiet精简输出模式 –c、–checksum打开校验开关,强制对文件传输进行校验 –a、–archive归档模式,表示以递归方式传输文件,并保持所有文件属性 –r、–recursive对子目录以递归模式处理 –R、–relative使用相对路径信息 –b、–backup创建备份,也就是对于目的已经存在有同样的文件名时,将老的文件重新命名为~filename –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保持文件时间信息 –W、–whole-file拷贝文件,不进行增量检测 –x、–one-file-system不要跨越文件系统边界 –B、–block-size=SIZE检验算法使用的块尺寸,默认是700字节 –e、–rsh=COMMAND指定替代rsh的shell程序 –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=TIMEIP超时时间,单位为秒 –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排除一个指定文件名中指定模式匹配的文件 –include-from=FILE不排除一个指定文件名中指定模式匹配的文件 –version打印版本信息 –address绑定到特定的地址 –config=FILE指定其他的配置文件,不使用默认的rsyncd.conf文件 –port=PORT指定其他的rsync服务端口 –blocking-io对远程shell使用阻塞IO –stats给出某些文件的传输状态 –log-format=FORMAT指定日志文件格式 –password-file=FILE从FILE中得到密码 –bwlimit=KBPS限制I/O带宽,KBytespersecond –h、–help显示帮助信息
5、常见使用实例
5.1 将本地的文件,同步到远程机器
rsync -avz --password-file=/root/rsyncd.pass /root/temp/ root@192.168.31.22:/home/laizy/tmp/
调换source和destination的位置,亦可完成远程机器到本地的数据同步。
5.2 使用ssh通道进行数据同步
rsync -avz --password-file=/root/rsyncd.pass -e ssh /root/temp/ root@192.168.31.22:/home/laizy/tmp/
5.3 删除不存在于源目录的目的地文件
rsync -avz --password-file=/root/rsyncd.pass --delete /var/opt/laizy/ /root/temp/
5.4 同步时不在目的地创建新文件
rsync -avz --password-file=/root/rsyncd.pass --existing /var/opt/lx/ /root/temp/
只对目的地已经有的文件进行同步,而不理会源目录新增的文件。
5.5 限制传输文件的大小
rsync -avz --password-file=/root/rsyncd.pass --max-size='100K' /var/opt/lx/ /root/temp/
以上命令限制传输的文件大小只能小于或等于100K,另可以使用M和G作为大小单位。
5.6全拷贝
rsync -avzW --password-file=/root/rsyncd.pass /var/opt/lx/ /root/temp/
默认情况下 rsync 采用增量拷贝,这样能节省带宽,在所同步文件不大的情况下,我们可以通过 -W 选项实现全拷贝。