在 GitHub 上编辑

大型数据集优化

为了跟踪使用 dvc adddvc repro 等命令添加的数据文件和目录,DVC 会将所有这些文件移动到项目的 缓存 中。

然而,在 工作区 中也需要存在与当前代码相匹配的已跟踪文件版本,因此可以将缓存中的一部分文件保留在工作目录中(通过使用 dvc checkout)。这是否意味着某些文件会在工作区和缓存之间重复?那样效率会很低! 尤其是对于大文件(几 GB 或更大)而言。

为了避免重复,同时让文件在两个目录中都存在,DVC 可以自动在工作区中为缓存数据创建文件链接。实际上,默认情况下,如果文件系统支持,DVC 会优先尝试使用 reflink*。

文件链接是文件系统中的轻量级条目,不包含实际文件内容,而是作为指向原始数据存储位置的快捷方式。它们常见于类 UNIX 操作系统所使用的文件系统中,并且根据文件名如何连接到系统中的 inode 而分为不同类型。

Inode 是用于定位和存储实际文件内容权限的元数据记录。有关技术细节(Linux),请参见 本文档 中的“文件链接”部分。在 Linux 上可使用 ls -i 命令列出 inode。

DVC 支持的三种链接类型各有优缺点:硬链接(Hard links)、软链接/符号链接(Soft/Symbolic links),以及较新系统中的 reflink。虽然 reflink 兼具所有优势且无风险,但目前大多数平台尚未广泛支持。硬链接和软链接在文件系统中能优化速度空间,但如果在 工作区 中直接修改由 DVC 跟踪的硬链接或符号链接文件,则可能导致缓存损坏。为防止此类问题,DVC 会将硬链接和符号链接设为只读,必须使用 dvc unprotect 才能安全地修改它们。

最后,第四种“链接”方式是直接从缓存复制文件,这种方式安全但效率较低——特别是对于大文件(几 GB 或更大)。

部分版本的 Windows(例如 Windows Server 2012+ 和 Windows 10 企业版)在 NTFSReFS 文件系统上支持硬链接或软链接。

文件链接类型的优点总结:

cache.type速度空间可编辑
reflinkxxx
hardlinkxx
symlinkxx
copyx

每种文件链接方法的具体细节如下,按其效率排序:

  1. reflink:写时复制*链接(Copy-on-write links),即“reflink”,是在可用情况下的最佳链接类型。它与硬链接/符号链接一样高效,但不会带来缓存损坏的风险,因为当你尝试就地编辑文件时,文件系统会自动复制该文件,从而保持链接的缓存文件完整不变。

    遗憾的是,目前仅少数文件系统支持 reflink(Linux:Btrfs、XFS、OCFS2;macOS:APFS),但未来大多数正在使用的文件系统都将支持这一功能。

  2. hardlink:如果您的代码仓库和缓存目录位于同一分区或存储设备上,硬链接是将数据链接到缓存的最高效方式。单个文件的硬链接数量可能受文件系统限制(NTFS:1024,EXT4:65,000)。当链接数量超过此限制时(在包含大量相同文件的仓库中可能发生),DVC 将自动回退到下一个可用的链接策略。

    请注意,硬链接的数据文件无法直接编辑,因此 DVC 默认会避免使用它们。但您可以选择取消链接或删除这些文件,然后替换为新文件。

  3. symlink:符号链接(又称“软链接”)是当您的代码仓库和缓存目录位于不同文件系统/磁盘时,将数据链接到缓存的最有效方式(例如,仓库位于 SSD 上以提高性能,而缓存目录位于 HDD 上以获得更大存储空间)。

    请注意,符号链接的数据文件无法直接编辑,因此 DVC 默认会避免使用它们。但您可以选择取消链接或删除这些文件,然后替换为新文件。

  4. copy:这是一种效率较低的“链接”策略,但在所有文件系统上都受支持。使用copy意味着不会创建文件链接,而是将被跟踪的文件作为副本同时存在于缓存和工作区中。适用于数据文件相对较小、复制操作不会造成明显存储性能负担的场景。

在 DVC 仓库中(需存在缓存文件夹),使用dvc version命令可查看当前系统支持的文件链接类型。

默认情况下,DVC 会优先尝试在系统支持时使用 reflink 作为缓存机制,但目前该功能尚不普遍,因此通常会回退到复制策略。如果您希望启用硬链接或软链接,可以按如下方式配置 DVC:

$ dvc config cache.type hardlink,symlink

更多详情请参考dvc config cache

请注意,在使用此cache.type配置时,工作区中的文件将处于只读模式,以防止缓存被破坏。有关在此类缓存配置下如何管理已跟踪文件,请参阅更新已跟踪文件

为了确保工作区中的数据文件与项目cache.type配置值保持一致,您可以使用dvc checkout --relink。更多信息请参见dvc checkout


* (写时复制) 链接或reflinks是现代文件系统中支持的一种文件链接类型。与硬链接或符号链接不同,编辑 reflinks 始终是安全的,因为原始缓存中的数据将保持不变。

内容

🐛 发现问题?告诉我们!或者修复它:

在 GitHub 上编辑

有疑问?加入我们的聊天,我们会为您提供帮助:

Discord 聊天