4个版本 (2个破坏性更新)
0.3.1 | 2023年9月24日 |
---|---|
0.3.0 | 2023年8月12日 |
0.2.0 | 2023年1月16日 |
0.1.0 | 2023年1月8日 |
#296 在 文件系统
18KB
359 行
Reflicate
通过在相同文件之间创建reflinks来去重数据。
安装
$ cargo install reflicate
$ export PATH=$PATH:~/.cargo/bin
免责声明
这是一个alpha质量的软件。请自由地在您的系统上测试此程序并报告错误。但请记住先备份。
摘要
reflicate [<directories...>] [-d] [-h] [-i <indexfile>] [-p] [-q]
Positional Arguments:
directories directories to deduplicate
Options:
-d, --dryrun do not make any filesystem changes
-h, --hardlinks make hardlinks instead of reflinks
-i, --indexfile store computed hashes in indexfile and use them in subsequent runs
-p, --paranoid compute sha256 hashes in addition to blake3 hashes
and do not trust precomputed hashes from indexfile
-q, --quiet be quiet
描述
Reflicate 会扫描指定的目录以查找相同文件并将它们reflink在一起。文件被认为是相同的,当它们具有相同的大小和相同的blake3哈希时。reflinked文件共享相同的磁盘块,因此磁盘空间只占用一次。在编辑文件时,它会将文件复制到不同的块中,因此可以安全地reflink当前具有相同内容但可能将来会不同的文件。
硬链接
硬链接与reflinks在两个方面有所不同
- 硬链接几乎由所有posix文件系统支持,而reflinks只被少数文件系统支持,例如XFS、BTRFS、OCFS2。
- 硬链接共享相同的inode,因此硬链接文件始终一起编辑。
索引文件
Reflicate 在索引文件中存储四个值:文件路径、文件大小、修改时间和blake3哈希。在后续运行中,它只对大小或修改时间不同的文件计算哈希。这意味着当使用索引文件时,程序可以更快地运行。
内部索引文件是CDB(常量数据库)和msgpack的组合。这意味着索引文件将在后续运行中被覆盖,因此如果您在不同的目录中使用reflicate
,请使用不同的索引文件。
偏执模式
默认情况下,reflicate 计算并比较blake3哈希,但在偏执模式下也使用sha256哈希。此外,在偏执模式下,总是计算所有哈希,因为可能可以操纵文件修改时间。
Systemd
可以使用Systemd计时器定期运行。为此,您需要运行以下命令
$ mkdir -p ~/.config/systemd/user/
$ cp systemd/* ~/.config/systemd/user/
$ systemctl --user daemon-reload
$ systemctl --user enable reflicate.timer
默认情况下,定期任务每周运行一次,并且reflicate
您的家目录。您可以通过编辑reflicate.service
和reflicate.timer
文件来根据您的需求进行调整。
展示
首先,让我们创建一个XFS文件系统,将其挂载,并创建一个测试目录。
$ dd if=/dev/zero of=test.img bs=1M count=100
$ mkfs.xfs test.img
$ sudo mount -o loop test.img /mnt
$ sudo mkdir /mnt/test
$ sudo chown `id -u` /mnt/test
然后创建两个相同和两个不同的文件。
$ dd if=/dev/zero of=/mnt/test/file1 bs=1M count=10
$ dd if=/dev/zero of=/mnt/test/file2 bs=1M count=10
$ dd if=/dev/zero of=/mnt/test/file3 bs=1M count=12
$ dd if=/dev/zero of=/mnt/test/file4 bs=1M count=15
现在我们可以看到,占用了53 MiB的磁盘空间(包括元数据)。
$ df -h /mnt
Filesystem Size Used Avail Use% Mounted on
/dev/loop0 95M 53M 42M 56% /mnt
让我们reflicate
测试目录。
$ reflicate /mnt/test/
/mnt/test/file2 => /mnt/test/file1 [10 MiB]
10 MiB saved
我们看到目前只占用了43 MiB的磁盘空间。
$ df -h /mnt
Filesystem Size Used Avail Use% Mounted on
/dev/loop0 95M 43M 52M 46% /mnt
让我们断开reflink并创建一个与file3内容相同的file2。
$ dd if=/dev/zero of=/mnt/test/file2 bs=1M count=12
$ df -h /mnt
Filesystem Size Used Avail Use% Mounted on
/dev/loop0 95M 55M 40M 59% /mnt
然后再次强复制测试目录。
$ reflicate /mnt/test/
/mnt/test/file3 => /mnt/test/file2 [12 MiB]
12 MiB saved
$ df -h /mnt
Filesystem Size Used Avail Use% Mounted on
/dev/loop0 95M 43M 52M 46% /mnt
最后,让我们删除测试文件系统。
$ sudo umount /mnt
$ rm test.img
依赖项
~2.7–4MB
~89K SLoC