跳到主要内容

上传协议

本文档描述了在 Xet 协议中如何将文件上传到内容寻址存储(CAS)服务。 该流程将输入文件转换为块,应用去重,将块分组为 xorbs,上传 xorbs,然后形成并上传引用这些 xorbs 的 shard。 这些步骤可以并发执行,但所有 xorbs 必须在引用它们的 shard 上传之前上传。 内容寻址使用哈希作为去重和完整性验证的稳定键。

Xet 对象类型

块(Chunk)

块是来自真实文件的数据切片。

块具有通过块哈希过程计算的相关哈希,其数据通过按照分块中定义的分块算法查找块边界来确定。

块约为 64KiB 的数据,最大为 128KiB,最小为 8KiB。 但是,对于文件的最后一个块或文件小于 8KiB 的情况,不强制执行最小块大小限制。

Xorb

Xorb 由一系列块组成。

Xorb 中的块不是简单地连接,而是按照 xorb 中的描述压缩并附加在标头之后。 块被收集到 xorb 中,以便更高效地上传和下载块的"范围"。 每个块都有一个关联的索引(从 0 开始),可以使用端部独占块索引范围(即 [0, 100))从 xorbs 中寻址块。

Xorbs 通过将文件中的块序列分组来创建,并在文件重建中引用以提供重建文件的指令。

Xorbs 具有根据 xorb 哈希过程 的说明计算的相关哈希。

Xorbs 的长度始终小于或等于 64MiB,平均包含 1024 个块,但此数字是可变的。

文件重建(File Reconstruction)

文件重建是使用来自 xorbs 的数据重新创建文件的"配方"。

每个文件重建由一系列"term"组成,其中每个 term 包含一个 xorb 哈希和一个块索引范围。 要重建文件,用户需要每个 term 在指定范围内的块,反序列化和解压缩并按 term 顺序连接。

Shard

Shard 是文件信息和 xorb 元数据的序列化表示。

一个 shard 可能包含多个文件重建,也可能不包含。 一个 shard 还可能包含有关 xorbs 的信息,特别是特定 xorb 中包含哪些块。

Shard 用于传达"文件上传"或在 CAS(内容寻址存储)中注册文件,以及注册与同一上传关联的 xorb 组。

Shard 还用于传达可用于使用全局去重 API 进行去重的 xorb 元数据。

Shard 格式在 shard 中指定。

备注

在 xet-core 中,shard 格式用于保持本地缓存,以便快速查找已知块以进行去重,xet 协议的其他实现者也可以选择为此目的重用 shard 格式,但这不是协议的要求。

步骤

1. 分块

使用 chunking 中描述的分块算法,首先将文件拆分为可变大小的块。 每个唯一块必须具有按照 块哈希部分 中描述计算的唯一哈希。 此块哈希将用于尝试将任何块与其他已知块进行去重。

2. 去重

给定块哈希,尝试查找该块是否已存在于 Xet 系统中。

对块进行去重是查找当前块哈希是否已存在,可以在当前上传过程中、在已知块的本地缓存中或使用全局去重 API 进行查找。

当块被去重时,不应重新上传到 CAS(通过在下一步中包含在 xorb 中),但在重建文件时,需要通过引用包含它的 xorb 和特定块索引来包含该块。

备注

请注意,去重被认为是一种优化,是上传过程的可选组件,但它提供了潜在的资源节省。

有关更多详细信息,请访问去重文档

3. Xorb 形成和哈希

将连续的块运行收集到 xorbs 中(每个 xorb 大约 64 MiB 总长度),保留每个运行中的顺序。参见形成规则:xorb。 Xorb 的内容寻址键使用 xorb 中的块计算。参见:hashing

给定 xorb 哈希,xorb 中的块可以在文件重建中引用。

4. Xorb 序列化和上传

每个 xorb 按照 xorb 格式定义序列化为其二进制表示。参见:xorb。 客户端通过 Xorb 上传 API 上传每个新 xorb。

序列化和上传步骤与收集块和哈希分离,因为这些步骤可以独立完成,同时在创建文件重建时仍引用 xorb。 但是,必须在引用它的文件重建在 shard 中上传之前上传 xorb。

5. Shard 形成,收集所需组件

使用可用的 xorbs 将每个文件映射到重建,文件重建必须指向 xorbs 内的块范围,这些范围引用文件中的每个块。 使用全局去重 API 的结果进行去重的块的 term 将使用 CAS 中已存在的 xorb 哈希。

然后对于每个文件:

  • 使用文件哈希过程计算文件哈希。
  • 对于每个 xorb 范围(一个"term"),计算验证哈希以便上传它。
    • 这些哈希用于确保在 shard 中上传文件的客户端权威地具有对实际文件数据的访问权限。
  • 计算文件内容的 sha256

有了这些组件,现在可以在 shard 格式中完全序列化文件信息块

除了文件信息之外,还需要收集为创建的新 xorbs 收集所有元数据。 此元数据是 xorb 哈希、每个块的哈希和长度、xorb 的序列化长度以及 xorb 的块长度总和。 有了这些组件,现在可以为每个 xorb 序列化一个 CAS 信息块

6. Shard 序列化和上传

给定上一节中收集的信息,按照 shard 规范 中指定的格式为一批文件序列化 shard。

客户端通过 CAS 服务器上的 shard 上传 端点上传 shard。 要成功,shard 引用的所有 xorbs 必须已经完成上传。

此 API 将文件注册为已上传。

备注

对于大批量文件或大批量大文件,如果序列化的 shard 将大于 64 MiB,你必须将内容拆分为多个 shard。

完成

在所有 xorbs 和所有 shard 成功上传后,完整上传被视为完成。 然后可以使用下载协议由任何客户端下载文件。

备注

如果此文件正在上传到 Hugging Face Hub,用户需要使用文件内容的 sha256 提交 git lfs 指针文件。

顺序和并发

上传过程中有一些自然的顺序要求,例如,你必须在计算块哈希之前确定块边界,并且必须收集一系列块以创建 xorb 来计算 xorb 哈希等。

但是,关于顺序有一个额外的强制要求:shard 引用的所有 xorbs 必须在该 shard 上传之前上传。 如果在调用 shard 上传 API 时 shard 引用的任何 xorb 尚未上传,服务器将拒绝该请求。 哈希用作 cas 信息部分中的条目和文件信息部分的数据条目中的所有 xorbs 都被视为由 shard"引用"。

完整性和幂等性

  • 块、xorbs 和 shard 的哈希确保完整性,并支持本地和全局范围内的去重。参见:hashing
    • 相同的块数据产生相同的块哈希
    • 相同的块集将产生相同的 xorb 哈希
  • 一致的分块算法确保相同的数据将在相同的边界处拆分为相同的块,允许这些块与其他数据匹配并去重。
  • 上传端点在内容寻址键方面是幂等的;重新发送已存在的 xorb 或 shard 是安全的。

序列图