1. 首页
  2. 文档
  3. IPFS集群 | IPFS Cluster
  4. 用户文档 | User Documentation
  5. 内部构件

内部构件

本节提供了有关IPFS集群内部的见解。它解释了集群如何在内部工作,收到引脚请求时会发生什么以及项目代码的组织方式。

共识算法

IPFS集群的设计理念是它最终应支持不同的一致性算法实现。共识层负责两件事:

  • 在所有集群对等节点上维护一致的视图  pinset,我们将其称为  shared state。这涉及控制如何执行状态更新,确保所有参与的对等节点共享完全相同的pinset。
  • 维护一致的视图  peerset,即哪些对等节点是集群的一部分。在一些共识实现中,明确定义  peerset 并使用一致性保证更新它与保持共享状态的其余部分一样重要。

无论上述考虑因素如何,我​​们对一致性状态视图的定义保持开放,因为不同的共识层实现可能会响应不同的一致性需求,或者提供不同的方法。一些共识方法也可能不担心保持 peerset 与其他人一样。

Raft

Raft共识实施被选为IPFS集群的默认共识层,原因如下:

  • 在小型集群中,它很容易理解和可靠,这对于数据中心部署来说是典型的
  • 它提供强大的一致性和防止网络分裂
  • hashicorp/raft 算法的实现很容易包装到  go-libp2p-consensus 界面上,并且支持插入 libp2p 传输。

Raft通过将日志条目提交到每个对等节点遵循的“分布式日志”来工作。在IPFS集群中,每个“Pin”和“Unpin”请求都是该日志中的日志条目。当对等节点接收到日志“Pin”操作时,它会更新其共享状态的本地副本,以指示CID现在被固定。

为了工作,Raft以多数选择集群“Leader”,这是唯一允许将条目提交到日志的对等节点。因此,Leader选举只有在至少一半节点在线时才能成功。日志条目和集群功能的其他部分只能在Leader存在时发生。

例如,使用触发对日志的提交操作  ipfs-cluster-ctl pin add <cid>。这将使用节点的API发送Pin请求。对等节点的Raft共识层将依次将请求转发给集群的Leader,后者将执行操作的提交并通知peerset中的所有对等节点。在下面的“固定项目”部分中对此进行了更详细的说明。

“节点添加”和“节点删除”操作也会触发日志条目(Raft内部),并且还依赖于健康的共识状态。修改集群对等节点是一项棘手的操作,因为它需要通知新对等节点的多地址给每个节点。如果对等节点在此操作期间关闭,则操作将失败,否则其他节点将不知道如何联系新成员。因此,建议在更改peerset之前删除并引导任何脱机的对等节点。

默认情况下,共识数据存储在raft 主配置文件旁边的子文件夹中。该文件夹存储两种类型的信息: 存储Raft日志的boltDB数据库和状态快照。当日志变得太大时,会定期执行日志中的快照(raft 有关选项,请参阅 配置部分)。当一个对等节点远远落后于追赶日志时,Raft可能会选择直接发送快照,而不是单独发送组成该状态的每个日志条目。此数据在集群对等节点的第一次启动时初始化,并在其整个生命周期内进行维护。删除或重命名 raft 文件夹可以有效地将对等节点重置为干净状态。只有处于干净状态的对等节点才应该引导到已经运行的集群。

在运行集群对等节点时,  非常重要的一点是共识数据文件夹不包含来自不同集群设置的任何数据或来自不同日志的数据。这实际上意味着不应混合不同的raft logs。在干净关闭时,IPFS集群对等体还将创建Raft快照。此快照是可用于导出或升级状态格式的状态副本。

共享状态,本地状态和ipfs状态

无论使用的共识实现如何,重要的是要了解IPFS集群处理三种类型的状态:

  •  共享状态 是由一致性算法维持和复制被保持在每一个集群对等节点。共享状态存储由IPFS集群跟踪的CID列表,它们的分配(固定它们的对等节点),它们的复制因子,名称以及集群的任何其他相关信息。
  • 本地状态 由每个对等点单独维护,并且表示由集群跟踪并分配给该特定对等点的CID的状态:ipfs状态(固定或不固定),修改时间等。本地状态可以根据需要从ipfs状态中机会性地构建
  • ipfs状态  是在ipfs(ipfs pin ls)上的实际状态,这是由ipfs守护程序保持。

在正常操作中,所有三个状态都是同步的,因为对共享状态的更新级联到本地和ipfs状态。此外,IPFS集群会定期触发同步操作。例如,直接从ipfs取消固定集群固定项将导致本地和ipfs状态不匹配。幸运的是,有办法检查每个状态:

  • ipfs-cluster-ctl pin ls 显示有关共享状态的信息。此命令的结果是在本地生成的,直接来自存储在对等节点中的状态副本。
  • ipfs-cluster-ctl status 显示有关每个集群对等节点中的本地状态的信息  。它通过聚合从每个集群成员收到的本地状态信息来实现。
  • ipfs-cluster-ctl sync 确保 本地状态  与ipfs状态匹配  。换言之,它确保集群期望被固定的内容实际上被固定在ipfs中,或者以其他方式将项标记为错误,或以其他方式标记有错误的项目。如上所述,这也会自动发生。每个同步操作都会触发ipfs pin ls --type=recursive 对本地节点的 调用。

最后一点,本地状态可能会显示错误的项目  。当项目花费太长时间来解锁/取消固定,或者ipfs守护程序变得不可用时,会发生这种情况。 ipfs-cluster-ctl recover <cid> 可以用来挽救这些项目。有关详细信息,请参阅下面的“固定项目”部分。

固定项目

ipfs-cluster-ctl pin add <cid> 将告诉IPFS集群固定(或重新固定)CID。

使用Raft共识实施时,这涉及:

  • 决定哪些对等节点将被分配CID(即哪些集群对等节点将要求ipfs固定CID)。这取决于复制因子(最小值和最大值)以及分配策略(下面有更多详细信息)。
  • 将引脚请求转发给Raft Leader。
  • 将引脚条目提交到日志。
  • 此时,会向用户返回成功/失败,但集群还有更多事情要做。
  • 接收日志更新并相应地修改共享状态  。
  • 更新本地状态。
  • 如果已经为对等节点分配了内容,则:
    • 对引脚请求进行排队并将引脚状态设置为 PINNING
    • 触发引脚操作
    • 等待它完成并将引脚状态设置为  PINNED

进程的第一部分(在提交条目之前)中的错误将返回给用户并且整个操作被中止。过程的第二部分中的错误将导致状态为的引脚 PIN_ERROR

决定固定CID的位置(哪个IPFS守护程序将存储它 – 接收分配)是一个复杂的过程。为了做出决定,所有可用的对等节点(报告有效/未到期指标的对等节点)都按allocator 组件排序  ,具体取决于其度量标准的值。这些值由配置的 informer提供。如果已经将CID分配给某些对等节点(在重新钉扎操作的情况下),则保留这些分配。

仅当分配因子(持有CID的健康同伴)低于replication_factor_min 阈值时才提供新分配  。在这些情况下,新的分配(以及现有的有效分配)将尝试总计尽可能多  replication_factor_max。当CID的分配因子在复制因子指示的边界内时,不采取任何动作。值“-1”,  replication_factor_min 和 replication_factor_max 表示“复制无处不在”的模式,其中每个节点都将固定CID。

默认复制因子在配置中指定,但每个Pin对象都将它们与共享状态中的自己的条目相关联  。更改现有引脚的复制因子需要重新固定它们(不足以更改配置)。您可以随时查看引脚的详细信息,包括其复制因子  ipfs-cluster-ctl pin ls <cid>。您可以使用  ipfs-cluster-ctl pin add <cid> 不同的复制因子随时重新固定。但请注意,如果新引脚与上一段中指定的方式不同,则只会提交新引脚。

要检查引脚的状态,请使用  ipfs-cluster-ctl status <cid>。可以触发错误状态的引脚重试  ipfs-cluster-ctl recover <cid>

固定(和取消固定)请求排队的原因是不对ipfs执行太多请求(即一次摄取多个引脚)。

取消固定项目

ipfs-cluster-ctl pin rm <cid> 将告诉IPFS集群取消固定CID。

该过程非常类似于上面描述的“固定项目”。从共享和本地状态擦除已移除的引脚。当请求status 给定CID的本地时  ,它将显示为  UNPINNED。错误将反映  UNPIN_ERROR 在引脚本地状态中。

添加项目

ipfs-cluster-ctl add <args> 将向集群添加内容。从版本 0.5.0开始支持此功能 。集群使用与go-ipfs相同的库来创建块并创建DAG(包括unixfs)。它还提供了用于配置进程执行方式的类似选项。

就像ipfs一样,要添加的文件使用多部分请求上传到  /add API端点。

集群使用adder 模块实现添加  。加法器模块可以使用自定义  ClusterDAGServices作为在存储时拦截所有块并使用它们执行集群操作的方法。我们提供了两个模块,它们也是  ipld.DAGService的实现

  • local集群DAG服务用于在集群中本地向多个IPFS守护进程添加内容。
  • sharding 群集DAG服务用于在集群中的多个IPFS守护程序之间分片内容(或DAG)分享。与本地不同,守护进程最终将持有部分DAG。

例如,local 每次在分块和构建DAG的过程中生成IPFS块时,  都会通知DAGService。然后,该模块对多个集群对等节点(分配)执行IPFSBlockPut广播调用,并将块发送到那些对等节点的IPFS连接器组件。导入过程完成后,它会触发集群  Pin 请求。

DHT服务

Cluster组件将go-libp2p-kad-dht 服务附加到libp2p主机。然后使用它来创建 路由主机,它使用DHT作为 PeerRouting)提供程序。这允许当其他对等节点在本地未知时(不是peerset的一部分),从其他对等点检索peer.ID的多重添加。

目前使用的DHT是Kademlia实现。来自其他对等节点的节点ID可以按照到当前对等节点的距离进行分类和,其优先记住那些更接近自身的对等节点。如果没有针对节点ID的地址,我们会联系最近的已知对等节点并请求它。这个过程重复进行,直到我们来到一个足够近的对等节点,记住我们正在寻找的peer.ID的细节。我们确保运行一个常规  dht bootstrap 进程,该进程使用空的peer.ID执行请求,从而遍历DHT,发现并连接到其中的其他对等节点。

我们目前不使用DHT来存储任何信息,仅用于对等节点发现(路由)。

DHT仅在对等体可以从头开始连接到 boostrapper 对等体时起作用,因此它具有访问和发现网络其余部分的起点。这个要求转化为集群中的两件事:

  • 首先,我们要求用户在peerstore 首次启动对等节点时在文件中至少有一个节点多地址  (并且不要使用  --bootstrap
  • 其次,我们在关闭peerstore 文件时保留所有已知的多地址  。

使用DHT的一个好处是,我们不需要让每个对等节点设备在启动/加入集群时立即连接并知道其他人的地址。相反,只要他们需要  Connect,他们就会使用DHT根据需要找到其他同伴。

后续步骤:  复合集群

这篇文章对你有帮助吗?

我们要如何帮助您?