rsync命令是一个远程数据同步工具,可通过LAN/WAN
快速同步多台主机间的文件。rsync使用所谓的rsync算法
来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。 rsync
是一个功能非常强大的工具,其命令也有很多功能特色选项,我们下面就对它的选项一一进行分析说明。
一、参数解析
-v, --verbose 详细模式输出。 |
二、工作模式
rsync
有六种
不同的工作模式,详细介绍如下:
拷贝本地文件:
规则
:当SRC
和DES
路径信息都不包含有单个冒号:
分隔符时就启动该模式;语法
:rsync [OPTION]... SRC DEST
;示例``:
rsync -a /data /backup`;
将本地机器的内容拷贝到远程机器:
规则
:当DST
路径地址包含单个冒号:
分隔符时启动该模式;语法
:rsync [OPTION]... SRC [USER@]host:DEST
;示例
:rsync -avz *.c foo:src
将远程机器的内容拷贝到本地机器:
规则
:当SRC
地址路径包含单个冒号:
分隔符时启动该模式;语法
:rsync [OPTION]... [USER@]HOST:SRC DEST
;示例
:rsync -avz foo:src/bar /data
;
从远程
rsync
服务器中拷贝文件到本地机:规则
:当SRC
路径信息包含::
分隔符时启动该模式;语法
:rsync [OPTION]... [USER@]HOST::SRC DEST
;示例
:rsync -av root@192.168.78.192::www /databack
;
从本地机器拷贝文件到远程
rsync
服务器:规则
:当DST
路径信息包含::
分隔符时启动该模式;语法
:rsync [OPTION]... SRC [USER@]HOST::DEST
;示例
:rsync -av /databack root@192.168.78.192::www
;
列出远程机的文件列表:
规则
:命令中省略掉本地机信息;语法
:rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
;示例
:rsync -v rsync://192.168.78.192/www
;
三、rsync的算法解析
3.1、分块checksum算法
首先,我们会把 DST文件
的文件均切分成若干小块,例如每块大小为512个字节(最后一块会小于这个数),然后对每块计算两个checksum
,计算checksum使用的算法如下:
rolling checksum(轮替校验和)
:这是一种弱checksum,会产生32位的checksum,使用的是Mark Adler发明的adler-32算法,用来快速弱检验是否相同;强checksum
:会产生128位的checksum,之前使用的是md4,现在使用的md5 hash算法,用来精准校验是否相同;
3.2、传输算法
同步目标端会把DST文件
的的一个checksum列表
传给同步源,这个列表里包括了三个东西:
- rolling checksum(32bits)
- md5 checksum(128bits)
- 文件块编号
3.3、checksum查找算法
同步源端拿到DST文件
的checksum数组
后,会把这个数据存到一个hash table
中,用rolling checksum
做hash
,以便获得O(1)
时间复杂度的查找性能,hash表
大小为16bits
的,因此hash表
槽位为2的16次方
,同时使用链表来解决碰撞冲突。
3.4、比对算法
- 取
SRC文件
的第一个
文件块(假设文件块大小为512
),也就是从SRC文件
的第1个字节到第512个字节,取出来后做rolling checksum
计算,在hash表
中查找计算好的值:找到对应的checksum
:- 由于
rolling checksum
是一个弱checksum,因为尝试比较md5
的checksum
,经过两次的checksum
比较,最终仍旧发生冲突的概率为1/(2^160)
,这种冲突概率太小,忽略不计; - 在比较
md5
的checksum
后,如果可以找到对应的匹配项,则表示在SRC文件
和DST文件
中有相同的文件块;
- 由于
未找到对应的checksum
:只要rolling checksum
或md5 checksum
其中有一个在DST文件
的checksum hash表
中找不到匹配项,那么就会触发算法对SRC文件
的rolling
动作,比对算法会住后移动1个字节
,对SRC文件
的字节位置为2-513
的文件块要做checksum
(需要特别注意:这里在原有checksum
的基础上进行调整就可以得出新的checksum
,而不必重新计算checksum
,这也是rolling
的精髓);
最终,在同步源这端,我们的rsync算法可能会得到下面这个样子的一个数据数组,图中,红色块表示在目标端已匹配上,不用传输(注:图中存在两块Chunk #5
指的是两个文件块在计算checksum
的时候存在hash冲突
,使用了链表进行解决),而白色的地方就是需要传输的内容(注意:这些白色的块是不定长的),这样,同步源这端把这个数组(白色的就是实际内容,红色的就放一个标号)压缩传到目的端,在目的端的rsync会根据这个表重新生成文件,这样,同步完成。