重复数据删除

时间:2013-04-23 14:03:08

标签: c# duplicates backup

我想将我的所有ms office,pdf,html,xml文件逐步备份到共享网络。我将以5mb的大块读取文件,我将在该数据上做MD5以考虑de dupe因子。我的问题是说上传后特定文件被修改了,现在我想逐步备份已更改的数据,如果我考虑相同的块大小,那么所有块看起来都会有所不同,我需要再次上传它们。那么有没有更好的重复数据删除方法,或者更好地了解所有指定文件的结构(原始阅读),然后处理de dupe?

2 个答案:

答案 0 :(得分:2)

有许多重复数据删除方法。必须知道文件的内部结构可能是最不具吸引力的选择 - 至少对我而言。我们做了类似于你所要求的事情并围绕它制作了一个产品。

一些观察结果;首先,你可能听说过这个问题,考虑到问题的年龄,MD5不是你最好的朋友。碰撞的概率太高,无法在这些类型的应用程序中使用。我们选择了SHA-1,还有很多其他类似产品的产品。

您通过简单的数据“分块”识别出这个问题......在早期文件插入的情况下,可能必须重写所有后续块。

首先,您可能会发现,在一定规模的阈值以下,这一点非常重要。改变较小文件的IO是你可能会吸收的东西。

但是,对于较大的文件,如果只有一小部分发生变化而不必重写所有数据会很好...并且对于许多大型可写文件,大的静态数据集中的小变化正是发生的事情。例如,具有内部数据库结构的文件。

如果可以认为这是一个技巧,那就是识别静态的数据范围。这相当于计算您识别的数据的哈希值。

例如,假设您在浏览文件时逐字节地计算滚动哈希值。如果你的散列函数是合理分配的,那么每个新字节都会产生一个与前一个字节的贡献相差很远的散列值。

识别哈希只是意味着哈希值位于您任意选择的某个值的某个子集中......您已决定代表 sentinel 哈希值。例如,您可能会认识到所有哈希值均匀分配的值。

当您识别哈希值时,您将捕获文件中该字节的偏移量,并将滚动哈希值重置为其初始状态。在文件的末尾,您将累积一个偏移列表。

现在,这些偏移之间的相对距离将取决于你对哈希识别器的选择程度。例如,如果您选择识别hash % 32 == 0,则会在相对较小的相对距离处产生大量偏移。如果你有hash % 65536 == 0,那么你将会有更少的间隔偏差。每个偏移之间的距离是可变的......有些将是非常小的,有些将是非常大的。 注意:大块是非常可压缩的。

这些偏移将成为断点......你将把块从偏移存储到偏移。在存储块之前,您将计算该块的哈希值(SHA-1哈希值,而不是运行哈希值)。如果您已经在存储中获得了这个块,则无需再次存储它。在您的存储中,文件将成为块列表。块可能最初来自一个文件,但也被识别为出现在其他文件中。重复数据删除!

您应用于运行哈希的选择性不仅控制块大小,还控制在大型文件中捕获“小更改”的程度。

此时,区分运行哈希和滚动哈希非常重要。当您在文件中滚动很长时间时,正在计算的内容是last n bytes上的散列非常重要,其中 n 是滑动帧的宽度。我们计算从offset到offset的哈希值。我们正试图找到我们认可的 n - 字节哨兵。

n的大小也很重要。你将计算0到n-1,然后是1到n,然后是2到n + 1等的哈希值。如果你考虑一下, n 表示将存在的最小块大小(除了哨兵之后的文件结尾)。

所以,在这一点上,你必须要思考,“Holey,这是很多哈希!”,你是对的;但它没有你想象的那么糟糕。选择正确的滚动哈希算法非常重要。有一种算法非常适合这种情况。我们使用的那个被称为Rabin-Karp滚动哈希,并使用Rabin fingerprint来发现哨兵偏移,它的美妙之处在于添加一个字节的贡献并删除一个字节的贡献是微不足道的,廉价的算法。

滚动哈希很重要(与运行哈希相反)的原因是更改检测。假设在更改之前发生了识别的标记偏移...然后在更改之后发生另一个识别的标记。仅存储这两个偏移之间的块。更改前的部分和更改后的部分将先前存储过。

答案 1 :(得分:0)

您可以检查rsync及其算法。

否则你可能需要做类似datadomain的事情。校验和变量chunksize,以便可以独立于给定文件中的偏移来识别数据段。请在网上搜索以查看他们的专利等。无法在此处进行全文写作。