Skip to main content

上传协议

本文档描述了在 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 中指定。

note

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

步骤​

1. 分块​

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

2. 去重​

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

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

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

note

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

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

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 将文件注册为已上传。

note

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

完成​

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

note

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

顺序和并发​

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

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

完整性和幂等性​

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

序列图​