本文档介绍了 uv 的全局缓存系统,该系统为下载的包、构建的 wheel、元数据和其他工件提供持久化存储,以提高跨操作的性能。缓存系统在 uv-cache crate 中实现,并与包括依赖项解析、包安装和工具管理在内的所有主要 uv 操作集成。
有关依赖项解析算法的信息,请参阅 依赖项解析。有关包安装机制的信息,请参阅 包管理。
缓存系统围绕一个分层目录结构构建,其中包含不同类型的数据的不同存储桶。每个存储桶都有自己的版本方案和存储布局,以确保跨 uv 版本的兼容性。
缓存结构组件
缓存围绕 crates/uv-cache/src/lib.rs137-149 中定义的几个关键抽象进行组织
Cache - 提供所有存储桶访问的主缓存抽象CacheBucket - 定义不同类型缓存数据的枚举CacheEntry - 缓存中的单个文件CacheShard - 分组相关缓存条目的子目录来源:crates/uv-cache/src/lib.rs137-672
每个缓存存储桶都存储特定类型的数据,并具有自己的目录结构和版本控制。存储桶系统允许不同的缓存格式独立演进。
主要缓存存储桶
在 crates/uv-cache/src/lib.rs748-988 中定义了主要缓存存储桶,包括:
| 存储桶 | 目的 | 结构 |
|---|---|---|
Wheel文件 | 预构建的 wheel 文件和元数据 | pypi/<package>/<wheel>.{whl,msgpack} |
SourceDistributions | 从源码构建的 wheel 文件 | <source>/<package>/<version>/<revision>/ |
简单 | 包索引响应 | <index>/<package>.rkyv |
Archive | 解压后的 wheel 目录 | <archive-id>/ |
解释器 | Python 解释器元数据 | <digest>.msgpack |
Git | Git 仓库克隆 | <url-digest>/ |
Environments | 工具环境 | <content-hash>/ |
来源:crates/uv-cache/src/lib.rs748-988
缓存提供了几种用于处理缓存数据的抽象,每种都具有特定的锁定和原子更新功能。
缓存条目管理
缓存条目通过 crates/uv-cache/src/lib.rs82-86 中定义的基于文件锁定的机制支持原子操作
CacheEntry::lock() - 获取排他锁以进行原子更新CacheShard::lock() - 锁定整个目录以进行批量操作Cache::entry() - 在特定存储桶内创建缓存条目缓存验证和新鲜度
缓存实现了 crates/uv-cache/src/lib.rs244-284 中的新鲜度检查系统来确定缓存条目是否仍然有效
来源:crates/uv-cache/src/lib.rs38-135
缓存支持可配置的刷新策略,以控制何时应重新验证或更新缓存数据。
刷新策略实现
刷新系统在 crates/uv-cache/src/lib.rs224-284 提供了三种策略
Refresh::None - 使用缓存数据而不重新验证Refresh::All - 强制重新验证所有缓存条目Refresh::Packages - 选择性地刷新特定包或路径特定包验证
诸如 must_revalidate_package() 和 must_revalidate_path() 之类的方法允许根据当前刷新策略对需要更新的缓存项进行精细控制。
来源:crates/uv-cache/src/lib.rs224-284
缓存支持多项管理操作,用于维护和清理,包括修剪未使用的条目和清除特定包。
缓存修剪逻辑
修剪实现在 crates/uv-cache/src/lib.rs397-520 执行了多项清理操作
引用跟踪
crates/uv-cache/src/lib.rs522-577 中的 find_archive_references() 方法构建了一个归档条目及其引用符号链接的映射,以便在修剪时识别未使用的归档文件。
来源:crates/uv-cache/src/lib.rs368-577 crates/uv/tests/it/cache_prune.rs1-385
缓存使用归档系统来高效地存储未解压的 wheel 文件,具有基于内容的去重和原子操作。
归档实现
归档由几个关键组件实现
ArchiveId 在 crates/uv-cache/src/archive.rs4-39 - 使用 nanoid 的唯一标识符Archive 结构体在 crates/uv-distribution/src/archive.rs6-40 - 关于已归档 wheel 的元数据归档持久化
crates/uv-cache/src/lib.rs286-306 中的 persist() 方法会原子地将临时目录移入归档存储桶并创建必要的链接。
跨平台链接
归档引用因平台而异
来源: crates/uv-cache/src/lib.rs286-306 crates/uv-distribution/src/archive.rs1-40 crates/uv-distribution/src/archive.rs1-41
缓存与 uv 的分发和 wheel 管理系统紧密集成,以提供高效的包存储和检索。
缓存集成点
分发系统通过几个关键接口与缓存集成:
RegistryWheelIndex,位于 crates/uv-distribution/src/index/registry_wheel_index.rs28-255 - 索引来自注册表的缓存 wheelBuiltWheelIndex,位于 crates/uv-distribution/src/index/built_wheel_index.rs15-242 - 管理从源代码构建的 wheelCachedWheel,位于 crates/uv-distribution/src/index/cached_wheel.rs15-182 - 表示缓存的 wheel 元数据哈希验证集成
缓存系统通过 Hashed trait 的实现来强制执行哈希验证,确保缓存的分发版本符合预期的完整性约束。
来源: crates/uv-distribution/src/index/registry_wheel_index.rs1-256 crates/uv-distribution/src/index/built_wheel_index.rs1-243 crates/uv-distribution/src/index/cached_wheel.rs1-183