Algorithm 一种高效的大文件扩散算法

Algorithm 一种高效的大文件扩散算法,algorithm,diff,rcs,Algorithm,Diff,Rcs,我必须存储两个文件A和B,它们都非常大(比如100GB)。然而,B在很大程度上可能与A相似,所以我可以存储A和diff(A,B)。这个问题有两个有趣的方面: 这些文件太大,我所知道的任何diff库都无法分析,因为它们在内存中 实际上我并不需要diff-diff通常有插入、编辑和删除,因为它是供人阅读的。我可以得到更少的信息:我只需要“新的字节范围”和“从任意偏移量复制旧文件中的字节” 在这些条件下,我目前不知道如何计算从a到B的增量。有人知道这个算法吗 同样,问题很简单:考虑到文件A和文件B非常

我必须存储两个文件A和B,它们都非常大(比如100GB)。然而,B在很大程度上可能与A相似,所以我可以存储A和diff(A,B)。这个问题有两个有趣的方面:

  • 这些文件太大,我所知道的任何diff库都无法分析,因为它们在内存中
  • 实际上我并不需要diff-diff通常有插入、编辑和删除,因为它是供人阅读的。我可以得到更少的信息:我只需要“新的字节范围”和“从任意偏移量复制旧文件中的字节”
  • 在这些条件下,我目前不知道如何计算从a到B的增量。有人知道这个算法吗

    同样,问题很简单:考虑到文件A和文件B非常相似,编写一个算法,以尽可能少的字节存储文件A和文件B


    附加信息:虽然大部件可能是相同的,但它们可能有不同的偏移量,并且出现故障。最后一个事实是,为什么传统的diff可能节省不了多少钱。

    看看RSYNCs算法,因为它的设计基本上就是为了做到这一点,所以它可以有效地复制增量。正如我所记得的,该算法有很好的文档记录。

    一个问题是文件中的记录大小,即偏移量是否可以逐字节更改,或者文件是否由1024B块组成。假设数据是面向字节的,可以执行以下操作:

  • 为文件a创建后缀数组。此数组是文件a所有索引值的排列。如果a有2^37个字节,则索引数组最容易用64位整数表示,因此每个字节(文件偏移量)对应于索引数组中的8个字节,因此索引数组的长度将为2^40个字节。比如说800 GB。您还可以仅为每1024个位置编制索引,以减小索引数组的大小。这将根据可复制片段的平均运行时间来确定包装质量

  • 现在,要贪婪地打包文件B,从偏移量o=0开始,然后使用索引数组查找A中与从“o”开始的数据相匹配的最长匹配项。在压缩文件中输出该对。这不需要任何16字节的编码,因此如果运行小于16字节,实际上会丢失空间。这可以通过使用位级编码和使用位标记来标记是对孤立字节(标记+8位=9位)还是偏移量/长度对(标记+40位+40位=81位)进行编码来轻松解决。在o处打包最长的片段后,将o增加到片段后的下一个字节,并重复此操作,直到文件末尾


  • 后缀数组的构造和使用很容易,您应该很容易找到引用。在高速应用程序中,人们改用后缀树或后缀尝试,它们操作起来更复杂,但查找速度更快。在您的情况下,您将把阵列放在辅助存储器上,如果打包阶段的运行速度不是问题,那么后缀阵列就足够了。

    这正是我们所知道的问题。最常用的方法是:

    • 以块形式读取文件:
      • 分割所谓“块”的数据。最常用的方法称为“使用Rabins指纹法的内容定义组块”(Content-defined Chunking-using-Rabins Fingerprinting method)()。使用这种分块方法可以在大多数数据集上实现更好的重复数据消除,而不是使用静态大小的分块(如图所示)
      • 使用加密指纹识别方法(例如SHA-256)对数据块进行指纹识别
      • 将指纹存储在索引中,如果指纹已知,则查找每个区块。如果指纹已知,则无需再次存储区块。只有当指纹未知时,才需要存储数据
    这样的重复数据消除算法不如(例如)精确,但对于大型数据集来说,它更快、更具可扩展性。分块和指纹识别的执行速度约为每核50MB/s(Java)。索引大小取决于冗余、块大小和数据大小。对于200 GB,它应该适合内存中的块大小,例如16KB

    压缩方法非常类似(例如谷歌BigTable使用),但我不知道有任何现成的命令行工具使用压缩技术


    开源项目包含了大部分必需的代码。但是,fs-c本身仅尝试测量内存中或使用集群中的冗余和analzye文件。

    根据您的性能要求,您可以对指纹块进行采样,并在匹配时进行增长。这样,您就不必对整个大文件运行校验和


    如果您需要任意字节对齐,并且真正关心性能,请查看,并使用它查找相似但未对齐的块。

    您可以使用
    rdiff
    ,这对大型文件非常有效。这里我创建了两个大文件的差异
    a
    B

  • 创建一个文件的签名,例如

    rdiff signature A sig.txt
    
  • 使用生成的签名文件
    sig.txt
    和另一个大文件,创建增量:

    rdiff delta sig.txt B delta
    
  • 现在
    delta
    包含了当您同时拥有
    A
    delta
    时重新创建文件
    B
    所需的所有信息。要重新创建B,请运行

    rdiff patch A delta B
    

  • 在Ubuntu中,只需运行
    sudo apt get install rdiff
    即可安装它。它相当快,我在电脑上的速度约为每秒40 MB。我刚刚在一个8GB的文件上试用过它,rsync使用的内存约为1MB。

    更改会有多少不同步?我的意思是,如果将两个文件并排放置,从旧文件复制的新文件中的数据,它们最多会偏离多少位置,或者相等的数据,它们偏离多少位置?po中的差异