为了跟踪使用 dvc add
、dvc repro
等添加的数据文件和目录,DVC 将所有这些文件移动到项目的缓存中。
但是,工作空间中还需要与当前代码匹配的跟踪文件的版本,因此可以将缓存文件的子集保留在工作目录中。 这是否意味着某些文件将在工作区和缓存之间重复? 那将没有效率!特别是对于大文件(几千兆字节或更大)。
为了使两个目录中的文件不重复,DVC 可以自动创建文件链接来指向工作空间中的缓存数据。 事实上,在默认情况下,如果文件系统支持,它将尝试使用 reflinks*
。
DVC 缓存支持的文件链接类型
文件链接是文件系统中的轻量级条目,不保存文件内容,而是作为原始数据实际存储位置的快捷方式。 它们在与类 UNIX 操作系统一起使用的文件系统中更为常见,并且有不同的种类,它们在将文件名连接到系统中的 inode 时有所不同。
Inodes 是元数据文件的记录,用于定位和存储对实际文件内容的权限。 有关技术详情 (Linux),请参阅 此文档 中的链接文件。 使用
ls -i
列出 Linux 上的 inode。
几种受支持的链接类型各有利弊:硬链接、软链接或符号链接,以及较新系统中的 Reflink。 虽然 reflinks 带来了所有的好处,而且没有任何顾虑,但大多数平台还没有普遍支持它们。 硬/软链接优化了文件系统中的速度和空间,但可能会破坏您的工作流程,因为更新工作空间中 DVC 跟踪的硬/符号链接文件会导致缓存损坏。 为了防止这种情况,DVC 通过将硬链接和符号链接设为只读来保护它们,需要使用 dvc unprotect
才能安全地修改它们。
最后,第四种“链接”方法是从缓存中复制文件,这是安全但低效的 - 特别是对于大文件(几 GB 或更多)。
某些版本的 Windows(例如:Windows Server 2012+ 和 Windows 10 Enterprise)在NTFS 和 ReFS 文件系统上支持硬链接或软链接。
文件链接类型的好处总结:
cache.type |
速度 | 空间 | 可编辑的 |
reflink |
x | x | x |
hardlink |
x | x | |
symlink |
x | x | |
copy |
x |
下面根据其效率进一步详细说明每种文件链接方法:
reflink
:Copy-on-write* 链接或reflinks
是最好的链接类型,如果可用的话。 它们与硬/符号链接一样高效,但不会带来任何缓存损坏的风险,因为如果您尝试在适当的位置编辑文件,文件系统会负责复制文件,从而保持链接的缓存文件完好无损。
不幸的是,目前仅在有限数量的文件系统(Linux:Btrfs、XFS、OCFS2;macOS:APFS)上支持 reflink,但将来大多数文件系统都将支持它们。
hardlink
:如果您的 repo 和缓存目录位于同一分区或存储设备上,硬链接是将数据链接到缓存的最有效方式。 一个文件的硬链接数可能受文件系统限制(NTFS:1024,EXT4:65,000)。 当链接数量超过此限制时,DVC 将回退到下一个可用的链接策略,这可能发生在具有很多相同文件的 repos 中。
请注意,硬链接的数据文件无法就地编辑,因此 DVC 默认避免使用这些文件。 但是,可以取消链接或删除它们,然后用新文件替换它们。
symlink
:如果repo和缓存目录位于不同的文件系统/驱动器上(库(repo)位于SSD上是为了提高性能,而缓存(cache dir)位于HDD上是为了更大的存储空间),符号链接(又名“软”)是将数据链接到缓存的最有效方式。
请注意,符号链接的数据文件不能就地编辑,因此 DVC 默认避免这些。 但是,可以取消链接或删除它们,然后用新文件替换它们。
copy
:一种低效的“链接”策略,但在所有文件系统上都受支持。 使用“复制”意味着没有文件链接,但跟踪的文件将被复制为缓存和工作区中存在的副本。 适用于数据文件相对较小的场景(复制它们不是存储性能问题)。
配置 DVC 缓存文件链接类型
默认情况下,如果您的系统上可用,DVC 会尝试对缓存使用 reflink,但这不是目前最常见的情况,因此它回退到复制策略。 如果您希望启用硬链接或软链接,您可以像这样配置 DVC:
$ dvc config cache.type hardlink,symlink 复制代码
请参阅
dvc config cache
,查看详细信息。
请注意,使用此cache.type
,您的工作区文件将处于只读模式,以保护缓存免受损坏。 请参阅更新跟踪文件了解如何在这些缓存配置下管理跟踪的文件。
为确保工作区中的数据文件与项目的cache.type
配置值一致,您可以使用dvc checkout --relink
。请参阅 dvc checkout
, 查看详细信息。
- copy-on-write 链接或"reflinks" 是在 UNIX 风格文件系统中链接文件的一种相对较新的方式。 与硬链接或符号链接不同,它们支持透明的 写入时复制。 这意味着编辑重新链接的文件始终是安全的,因为该文件的所有其他链接都将显示更改。