`
wusuoya
  • 浏览: 641707 次
  • 性别: Icon_minigender_2
  • 来自: 成都
社区版块
存档分类
最新评论

rsync 的核心算法

阅读更多

rsync 是 unix/linux下同步文件的一个高效算法,它能同步更新两处计算机的文件与目录,并适当利用查找文件中的不同块以减少数据传输。rsync中一项与 其他大部分类似程序或协定中所未见的重要特性是镜像是只对有变更的部分进行传送。rsync可拷贝/显示目录属性,以及拷贝文件,并可选择性的压缩以及递 归拷贝。rsync利用由Andrew Tridgell 发明的算法。这里不介绍其使用方法,只介绍其核心算法。我们可以看到,Unix下的东西,一个命令,一个工具都有很多很精妙的东西,怎么学也学不完,这就是Unix的文化 啊。

本来不想写这篇文章的,因为原先发现有很多中文blog都说了这个算法,但是看了一下,发现这些中文blog要么翻译国外文章翻译地非常烂,要么就 是介绍这个算法介绍得很乱让人看不懂,还有错误,误人不浅,所以让我觉得有必要写篇rsync算法介绍的文章。(当然,我成文比较仓促,可能会有一些错 误,请指正)

问题

首先, 我们先来想一下rsync要解决的问题,如果我们要同步的文件只想传不同的部分,我们就需要对两边的文件做diff,但是这两个问题在两台不同的机器上, 无法做diff。如果我们做diff,就要把一个文件传到另一台机器上做diff,但这样一来,我们就传了整个文件,这与我们只想传输不同部的初衷相背。

于是我们就要想一个办法,让这两边的文件见不到面,但还能知道它们间有什么不同。这就出现了rsync的算法。

算法

rsync的算法如下:(假设我们同步源文件名为fileSrc,同步目的文件叫fileDst

 

1)分块Checksum算法 。首先,我们会把fileDst的文件平均切分成若干个小块,比如每块512个字节(最后一块会小于这个数),然后对每块计算两个checksum,

  • 一个叫rolling checksum ,是弱checksum,32位的checksum,其使用的是Mark Adler发明的adler-32 算法,
  • 另一个是强checksum,128位的,以前用md4,现在用md5 hash算法。

为什么要这样?因为若干年前的硬件上跑md4的算法太慢了,所以,我们需要一个快算法来鉴别文件块的不同,但是弱的adler32算法碰撞概率太高了,所以我们还要引入强的checksum算法以保证两文件块是相同的。也就是说,弱的checksum是用来区别不同,而强的是用来确认相同 。(checksum的具体公式可以参看这篇文章

2)传输算法。 同步目标端会把fileDst的一个checksum列表传给同步源,这个列表里包括了三个东西,rolling checksum(32bits)md5 checksume(128bits)文件块编号

我估计你猜到了同步源机器拿到了这个列表后,会对fileSrc做同样的checksum,然后和fileDst的checksum做对比,这样就知道哪些文件块改变了。

但是,聪明的你一定会有以下两个疑问:

  • 如果我fileSrc这边在文件中间加了一个字符,这样后面的文件块都会位移一个字符,这样就完全和fileDst这边的不一样了,但理论上来说,我应该只需要传一个字符就好了。这个怎么解决?
  • 如果这个checksum列表特别长,而我的两边的相同的文件块可能并不是一样的顺序,那就需要查找,线性的查找起来应该特别慢吧。这个怎么解决?

很好,让我们来看一下同步源端的算法。

3)checksum查找算法 。同步源端拿到fileDst的checksum数组后,会把这个数据存到一个 hash table中,用rolling checksum做hash,以便获得O(1)时间复杂度的查找性能。这个hash table是16bits的,所以,hash table的尺寸是2的16次方,对rolling checksum的hash会被散列到0 到 2^16 – 1中的某个整数值。(对于hash table,如果你不清楚,建议回去看大学时的数据结构教科书)

顺便说一下,我在网上看到很多文章说,“要对rolling checksum做排序”(比如这篇这篇 ),这两篇文章都引用并翻译了原作者的这篇文章 ,但是他们都理解错了,不是排序,就只是把fileDst的checksum数据,按rolling checksum做存到2^16的hash table中,当然会发生碰撞,把碰撞的做成一个链表就好了。这就是原文 中所说的第二步——搜索有碰撞的情况。

4)比对算法 。这是最关键的算法,细节如下:

4.1)取fileSrc的第一个文件块(我们假设的是512个长度),也就是从fileSrc的第1个字节到第512个字节,取出来后做rolling checksum计算。计算好的值到hash表中查。

4.2)如果查到了,说明发现在fileDst中有潜在相同的文件块,于是就再比较 md5的checksum,因为rolling checksume太弱了,可能发生碰撞。于是还要算md5的128bits的checksum,这样一来,我们就有 2^-(32+128) = 2^-160的概率发生碰撞,这太小了可以忽略。如果rolling checksum和md5 checksum都相同,这说明在fileDst中有相同的块,我们需要记下这一块在fileDst下的文件编号

4.3)如果fileSrc的rolling checksum 没有在hash table中找到,那就不用算md5 checksum了。表示这一块中有不同的信息。总之,只要rolling checksum 或 md5 checksum 其中有一个在fileDst的checksum hash表中找不到匹配项,那么就会触发算法对fileSrc的rolling动作。于是,算法会住后step 1个字节,取fileSrc中字节2-513的文件块要做checksum,go to (4.1) - 现在你明白什么叫rolling checksum了吧。

4.4)这样,我们就可以找出fileSrc相邻两次匹配中的那些文本字符,这些就是我们要往同步目标端传的文件内容了。

图示

怎么,你没看懂? 好吧,我送佛送上西,画个示意图给你看看(对图中的东西我就不再解释了)。

这样,最终,在同步源这端,我们的rsync算法可能会得到下面这个样子的一个数据数组,图中,红色块表示在目标端已匹配上,不用传输(注:我专门 在其中显示了两块chunk #5,相信你会懂的),而白色的地方就是需要传输的内容(注意:这些白色的块是不定长的),这样,同步源这端把这个数组(白色的就是实际内容,红色的就放 一个标号)压缩传到目的端,在目的端的rsync会根据这个表重新生成文件,这样,同步完成。

最后想说一下,对于某些压缩文件使用rsync传输可能会传得更多,因为被压缩后的文件可能会非常的不同。对此,对于gzip和bzip2这样的命令,记得开启 “rsyncalbe” 模式。

 

原文引用:http://coolshell.cn/articles/7425.html

分享到:
评论

相关推荐

    rsync的核心算法

    rsync是unix/linux下同步文件的一个...这里不介绍其使用方法,只介绍其核心算法。我们可以看到,Unix下的东西,一个命令,一个工具都有很多很精妙的东西,怎么学也学不完,这就是Unix的文化啊。首先,我们先来想一下rs

    基于java实现的,以rsync算法原理为基础的二进制文件差异比较处理.zip

    首先,我们来深入理解rsync算法的核心思想。rsync算法主要依赖于“ rolling checksum”(滚动校验和)的概念。这个概念是通过对文件的每个小块计算校验和,并与之前计算过的校验和进行比较,来找出文件之间的相似性...

    linux 下rsync文件夹同步配置

    rsync是一种用于文件传输的开源软件,其核心功能是文件同步,能够快速、增量地同步文件或目录。它利用“差分压缩”算法,只传输两个文件差异部分,极大提高了数据传输效率。此外,rsync支持多种传输协议,如TCP/IP,...

    Algorithm-js-rsync.zip

    Rsync的核心算法是基于增量传输,这意味着它只发送源和目标文件之间的差异部分,而不是整个文件。这大大减少了网络带宽的使用,提高了同步速度。JavaScript版本的rsync可能会使用类似的技术,通过比较文件的哈希值或...

    linux rsync命令使用手册

    Rsync 的核心优势在于其实现了高效的文件同步。它通过以下机制来确定哪些文件需要传输: 1. **快速检查算法**:默认情况下,Rsync 使用一种“快速检查”算法来查找那些在大小或最后修改时间上发生变化的文件。 2. *...

    rsync一工作模式及语法

    rsync 的核心特性在于其差异传输算法(Delta Transfer Algorithm),即只传输源文件与目标文件之间的差异部分,从而极大地提高了文件传输效率。 #### 二、rsync工作模式 rsync 支持两种主要的工作模式:基于远程 ...

    android_external_rsync,rsync的android本地端口.zip

    2. 检验算法:rsync使用滚动校验算法,可以快速检测到文件内容的变化,确保同步的准确性。 3. 压缩传输:rsync支持在传输过程中对数据进行压缩,进一步节省带宽资源。 4. 多种同步模式:rsync提供多种同步模式,如...

    Rsync4.1.0客户端+服务端

    首先,让我们深入了解一下Rsync的核心功能。Rsync的主要用途是进行本地或远程的数据备份和同步。它的同步算法非常高效,能够仅传输两份文件之间的差异部分,大大减少了网络带宽的消耗。此外,Rsync还支持增量备份,...

    Rsync实现文件备份同步

    Rsync是一款开源的文件传输协议,其核心功能是能够在本地或网络环境中快速地同步文件和目录。Rsync以其增量复制技术著称,只传输两份文件之间的差异部分,从而大大减少了数据传输量。此外,Rsync还支持压缩、排除...

    Rsync win版本客户端和服务端+linux服务端

    Rsync的核心功能在于其高效的数据同步能力,它能快速地更新只改变了的部分,而不是重新传输整个文件。这得益于其独特的"增量传输"算法。Rsync支持本地或远程的文件和目录同步,可以进行单向或双向同步,并且具备压缩...

    Rsync 服务器搭建

    Rsync 的核心特性是其独特的“rsync 算法”,这种算法能快速识别并只传输文件的差异部分,从而大大提高了文件同步的速度。 Rsync 拥有多项实用特性,例如: 1. 可以同步整个目录结构和文件系统。 2. 支持保留符号...

    rsync windows 64位版

    cwRsync包括了rsync核心以及必要的Cygwin库,使得rsync命令可以在64位Windows操作系统上顺利运行。 rsync的工作原理主要基于三方面的特性: 1. **增量传输**:rsync只传输文件的差异部分,而不是整个文件,这极大地...

    rsync-3.0.9.tar.gz

    1. **增量同步**:rsync采用了一种独特的增量传输算法,只同步源文件与目标文件之间的差异部分,极大地提高了数据传输效率,尤其适用于大量文件和大文件的同步。 2. **文件过滤**:rsync支持通过规则文件(.rsync-...

    rsync的linux库

    以上就是关于librsync在Linux环境下的详细介绍,包括其核心算法、功能特性、使用方法以及常见应用场景。librsync作为一个强大的库,为开发者提供了高效的数据同步解决方案,使得rsync的强大功能得以在更多场合得到...

    rsync、pscp、ssh

    rsync支持多种同步模式,如双向同步、镜像备份,并且可以利用gzip或bzip2等算法进行压缩,以减少网络传输的数据量。此外,通过与ssh结合,rsync可以安全地在不安全的网络环境中进行文件传输。 2. **pscp** PSCP...

    rsync-3.0.7.tar.gz

    rsync的工作机制基于称为“delta transfer algorithm”的算法,这个算法能够检测出文件之间的相似性,并仅传输差异部分。因此,即使面对大量数据,rsync也能保持较高的速度和资源利用效率。 在使用rsync时,用户...

    图解rsync数据同步部署文档

    Rsync的核心算法可概括为五个步骤: 1. **分割文件**:目标机器(假设为2号机)将文件B按固定大小S字节分割成多个数据块,最后一块可能小于S。 2. **执行校验**:对每个数据块执行两次校验:一次为32位的滚动弱校验...

    rsync-3.1.3源码

    2. **同步算法**:rsync的核心算法在`rsync Algorithm`模块中实现,包括`rsync_delta.c`和`rsync_module.c`等文件。这些算法通过比较文件的块来识别相似性,并构建出一个描述差异的“delta”。 3. **过滤规则**:...

Global site tag (gtag.js) - Google Analytics