Bitswap 作为 IPFS 网络数据交换接口的具体实现,主要关注如何快速、高效获取需要的区块。
原文标题:《揭秘 IPFS 数据交换模块 Bitswap》 撰文:马耀耀,就职于数据网格实验室 BitXMesh
星际文件系统(InterPlanetary File System,缩写 IPFS)是一个旨在创建持久且分布式存储和共享文件的网络传输协议。
与传统的文件系统不同,它是一种基于内容寻址的点对点超媒体分发协议。
IPFS 网络中的节点构成一个分布式文件系统网络,其中 Bitswap 是 IPFS 的核心模块,负责与网络中其他节点之间请求和发送数据块。
IPFS 将文件分解为称为 block 的数据块,这些块由内容标识符(CID)标识。
IPFS 文件内容存储在不同的节点上,每个节点存储 root block,少量节点存储完整文件数据,大部分节点存储部分文件 block。因为 block 分散存储在不同节点,Bitswap 协议解决了从多个节点高效获取全部数据块的问题。
本文基于 Bitswap v0.3.3 版本进行分析。
IPFS 向 Bitswap 获取 block,Bitswap 是 IPFS exchange 接口的具体实现,负责完成 IPFS 网络数据交换功能。
Bitswap 协议内容比较繁琐,为了降低实现复杂度协议划分为 block 请求模块、block 发送模块、会话管理模块、block 提供者发现模块、网络模块等。
Bitswap 模块负责接收新的消息并且提供对外数据交换接口。
session 管理模块用来管理多个 session,每个 session 管理一组文件的下载,来提高下载效率。
block 发送模块负责管理向其它节点发送数据块。block 请求模块负责管理数据块的请求。block 提供者发现模块负责通过 DHT 网络发现网络中的数据块,通常 session 找不到已拥有所需 block 的节点时会调用此模块进行数据块发现。
为了完成节点间 block 交换,Bitswap 定义了通信消息及通信协议。
Bitswap 消息处理流程:
Bitswap 模块负责接收新消息并且实现对外的数据交换接口。
当接收到新消息后,Bitswap 处理流程:
Bitswap 通过 Facade Pattern 提高了模块使用的便利性,使得 Bitswap 子系统的用法变得简单,避免了 IPFS 和 Bitswap 的高度耦合。
session 管理模块用来管理多个数据块下载 session,每个 session 管理一组文件的下载。
当 SessionManager 收到新消息时,它将
Session 管理模块通过协调多个 session 的数据需求来提高数据交互的效率,避免数据块的重复请求、发送。
Session 管理一组文件的下载,用来提高一组文件块,比如单个文件下载效率。当 IPFS 调用 Bitswap 时,Bitswap 会创建一个新的 Session 并调用 Session 的相应方法,比如 GetBlocks() 获取 blocks。Session 会管理一个节点列表,数据获取过程只会向 session 中的节点获取数据,而不是所有的连接节点。当 Session 中的节点都没有某个 block 时,Bitswap 才会通过 DHT 获取具有 block 的节点并加入 session。
由于 session 刚开始没有任何节点,处于「discovery」模式。当 IPFS 最初从 session 请求 block 时,该 session 处理流程如下:
当 session 收到带有「 HAVE」或「 block」的消息时,它将通知 SessionPeerManager 组件。
当 session 收到带有「 block」的消息时,它将通知 SessionInterestManager 组件。
一旦 session 具有节点,就不再处于「discovery」模式。当 IPFS 请求后续 block 时,session 将通知 sessionWantSender 组件。sessionWantSender 组件通知 PeerManager 组件向会话中的节点发送「 want-have」和「 want-block」消息。
对于 session 所需的每个 block,sessionWantSender 组件通过与 BlockPresenceManager 组件核对哪些节点已为该 block 发送了「 HAVE」,来确定哪个节点最有可能拥有该 block。如果多个节点发送过「 HAVE」,则会根据先前请求回复速度来选择节点。
由于 DHT 内容发现速度慢并且网络带宽消耗大,session 通过向一组含有目标数据块可能性大的节点获取数据,从而大大提高了数据块获取的效率。
block 发送模块负责管理向其它节点发送数据块,包含节点需求管理组件(Ledger)和消息发送任务队列(PeerTaskQueue)。
Engine 是 block 发送模块的处理类,当 Engine 被告知有新的 wants 时
PeerTaskQueue 组件通过对任务进行优先级排序,发送队列中数据量最少的节点方具有最高优先级,通过这种流控措施,提高数据块发送处理效率。
Block 请求模块负责管理数据块的请求。PeerManager 组件为连接到 Bitswap 的每个节点创建一个 MessageQueue 组件,记录了「want-have」 、「want-block」已发送到哪个节点,并将任何新的 wants 定向到正确的节点。并且 MessageQueue 组件通过合并多个 want 为一条消息,然后将该消息发送给节点,从而提高了消息发送效率。
当 Bitswap 找不到已拥有所需 block 的节点时,它会使用 DHT 进行内容发现。Bitswap 通过 ProviderQueryManager 组件管理这些请求,ProviderQueryManager 组件对请求进行速率限制,并对进行中的请求进行重复删除处理。
Bitswap 作为 IPFS 网络数据交换接口的具体实现,设计并实现了一套高效的节点间交换数据的协议。
协议主要关注点是如何快速、高效获取需要的 block,其中包括节点选择策略,如何最大化利用每个节点的能力。
Bitswap 通过 Facade Pattern 提高了模块使用的便利性,在具体实现上解耦复杂依赖到各功能模块,从而降低系统实现的复杂度。