Xet 块级去重规范
概述
块级去重是 Xet 系统中的一项基本优化技术,通过识别和共享跨文件和仓库的相同内容块(块)来消除冗余数据。 本规范详细说明了在保持数据完整性和访问控制的同时实现高效存储和传输的过程、算法和安全机制。
Xet 中的去重在块级别而不是文件级别运行,提供细粒度的去重功能,即使文件差异很大也能识别共享内容。 这种方法对于机器学习和数据科学工作流中常见的场景特别有效,例如:
- 具有增量更改的 数据集的多个版本
- 共享共同层或参数的模型检查点
- 具有相似内容的文档和配置文件
- 只有部分内容在版本之间发生变化的大文件
核心概念
块
块是使用内容定义分块(CDC)和滚动哈希函数从文件派生的可变大小内容块。块是 Xet 中去重的基本单位。
- 目标大小:64KB(可配置)
- 大小范围:8KB 到 128KB(最小和最大约束)
- 标识:每个块由其加密哈希(MerkleHash)唯一标识
Xorbs
Xorbs 是聚合多个块以实现高效存储和传输的对象:
- 最大大小:64MB
- 最大块数:每个 xorb 8,192 个块
- 目的:将多个块批处理在一起,以减少上传和下载块组时的元数据和网络开销
Shard(Xorb 列表)
Shard 是包含可以针对其进行去重的 xorbs 列表的对象(对于去重上下文,忽略 shard 格式的文件信息部分)。
- 最大大小:64MB
- 目的:在全局去重请求的肯定回复上提供格式,包含有关 CAS 系统中已存在的 xorbs 的信息。
CAS(内容寻址存储)
CAS 系统提供底层存储基础设施:
- 内容寻址:所有对象都通过其加密哈希存储和检索
- 不可变性:一旦存储,文件内容无法修改
- 去重:相同内容在存储级别自动去重
去重过程
1. 文件处理和分块
当文件被处理以上传时,它经历以下步骤:
- 分块:使用 GearHash 算法的内容定义分块创建文件数据的可变大小块
- 哈希计算:使用加密哈希函数(基于 Blake3 的 MerkleHash)对每个块的内容进行哈希
- 块对象创建:块用包括哈希、大小和数据的元数据包装
2. 多级去重策略
Xet 采用三级去重策略,以在最小化延迟的同时最大化效率:
级别 1:本地会话去重
范围:当前上传会话 机制:内存哈希查找表 目的:消除当前文件或会话内的冗余
好处:
- 最快的查找(内存中)
- 零网络开销
- 即时去重反馈
级别 2:缓存元数据去重
范围:以前上传的文件和会话 机制:本地 shard 文件元数据缓存 目的:利用针对最近上传内容的去重
好处:
- 快速本地磁盘访问
- 无网络延迟
- 跨会话持久化
级别 3:全局去重 API
范围:整个 Xet 系统 机制:具有 HMAC 保护的全局去重服务 目的:发现跨所有用户和仓库的去重机会
3. 全局去重过程
全局去重系统提供跨 Xet 系统管理的所有数据的去重功能:
资格标准
并非所有块都有资格进行全局去重查询以管理系统负载:
- 第一个块:每个文件的第一个块始终有资格。
- 哈希模式匹配:如果哈希的最后 8 个字节解释为小端 64 位整数 % 1024 == 0,则块有资格。
建议: 间距约束:全局去重 API 经过优化,当有匹配时返回有关附近块的信息。考虑仅对每 ~4MB 数据中的合格块发出请求。
查询过程
- 后台查询:全局去重查询应该异步运行,以避免阻塞上传
- HMAC 保护:使用 HMAC 密钥保护块哈希
- Shard 响应:找到匹配时,API 返回包含以下内容的 shard:
- CAS 信息部分:包含有关存储块的许多 xorbs 的元数据
- HMAC 密钥:包含在用于加密块哈希的 shard 元数据标头中
- 加密块匹配:返回的 shard 中的所有块哈希都已使用 HMAC 密钥加密
- 匹配发现过程:要查找匹配,客户端必须:
- 使用提供的 HMAC 密钥加密其块哈希
- 在 shard 的块列表中搜索加密的哈希
- 对于后续块,重复加密和搜索过程
- 跟踪原始(未加密)块哈希,同时注意哪个 xorb 包含该块
- 元数据缓存:客户端下载并缓存 shard 元数据以供将来去重
HMAC 安全机制
全局去重使用 HMAC(基于哈希的消息认证码)来保护块哈希,同时启用去重。
安全属性:
原始块哈希永远不会从服务器传输到客户端;客户端必须加密其原始块哈希并找到匹配,才能知道系统中存在原始块哈希。 他们可能知道此块哈希,因为他们拥有此数据,匹配使他们知道哪个 xorb 具有此块哈希以及 xorb 中的位置,但没有透露该 xorb 或其他 xorbs 中的任何其他原始块哈希。
技术实现细节
块哈希计算
每个块都使用加密哈希函数(基于 Blake3 的 MerkleHash)对其内容进行哈希,以为内容寻址创建唯一标识符。 参见有关哈希的部分。
Xorb 形成
当需要存储新块时,它们根据大小和计数限制聚合到 xorbs 中。如果添加新块会超过最大 xorb 大小或块计数,则完成并上传当前 xorb。参见有关 xorb 形成的部分