可以参考这篇文章
https://www.a-programmer.top/2021/10/15/ZFS%E7%B3%BB%E5%88%97%EF%BC%88%E4%B9%9D%EF%BC%89%E5%8E%8B%E7%BC%A9%E4%B8%8E%E6%95%B0%E6%8D%AE%E5%8E%BB%E9%87%8D/数据去重( Deduplication ,重复数据删除 /重删)
我们还有另一种与压缩相结合的方法来节约磁盘空间,那就是重复数据删除。现在,有三种主要的重复数据删除类型:文件、块和字节。文件重复数据删除是性能最高、系统资源成本最低的。每个文件都使用加密哈希算法进行哈希,比如 SHA-256 。如果哈希值匹配多个文件,则不将新文件存储在磁盘上,而是在元数据中引用原始文件。这可以节省大量空间,但也有一个严重的缺点。如果文件中的单个字节发生了变化,哈希值将不再匹配,这意味着我们不能再在文件系统元数据中引用整个文件。因此,我们必须将磁盘所有块做一个复本,对于大文件,这对性能有很大的影响。
另一种极端情况是字节重复数据删除,这种重复数据删除方法成本最高,因为您必须保留“锚点”,以确定重复数据删除和唯一字节区域的开始和结束位置。毕竟,字节就是字节,是不知道哪些文件需要它们,它只不过是一个数据的海洋。这种重复数据删除技术适用于文件可能被存储多次的存储,即使文件没有在相同的块下对齐,比如邮件附件。
块重复数据删除处于三者中间位置。ZFS 仅支持块重复数据删除。块重删共享文件中所有相同的块。这允许我们只在磁盘上存储唯一的块,并在 RAM 中引用共享块。它比字节重复数据删除更高效,比文件重复数据删除更灵活。然而,它有一个缺点——它需要大量的内存来记录哪些块是共享的,哪些不是。不过,因为文件系统读写数据是以块的方式,所以对现代文件系统使用块重复数据删除是最有意义的。
共享块被存储在所谓的“重复数据删除表”中,文件系统上重复的块越多,这个表就越大。每次写入或读取数据时,重复数据删除表都会被引用。这意味着您希望将整个重复数据删除表保存在快速 RAM 中。如果您没有足够的 RAM ,那么表将溢出到磁盘上。这可能会对存储的性能产生巨大的影响,无论是读数据还是写数据。
数据去重的开销
所以这还有个问题:你需要多少内存来存储你的重复数据删除表?这个问题没有一个简单的答案,但是我们可以对如何处理这个问题有一个很好的总体思路。首先,查看存储池中的块数量。你可以看到这个信息,用如下的命令(耐心点-在它给出报告之前,可能需要一段时间来扫描文件系统中的所有块):
# zdb -b rpool
Traversing all blocks to verify nothing leaked ...
No leaks (block sum matches space maps exactly)
bp count: 288674
bp logical: 34801465856 avg: 120556
bp physical: 30886096384 avg: 106992 compression: 1.13
bp allocated: 31092428800 avg: 107707 compression: 1.12
bp deduped: 0 ref>1: 0 deduplication: 1.00
SPA allocated: 31092244480 used: 13.53%
在本例中,存储池“rpool”中有 288674 块被使用(查看“bp count”)。池中的每个重复数据删除块需要大约 320 字节的内存。因此,对于 288674 块乘以 320 字节 /块,我们得到大约 92 MB 。文件系统大约有 200 GB 大小,所以我们可以假设重复数据删除只能增长到大约 670 MB ,尽管它只有 13.53%被填满。也就是说,每 1GB 的文件系统需要 3.35 MB 的重复数据删除数据,或者每 1TB 的磁盘需要 3.35 GB 的 RAM 。