深入理解 Helia 架构设计
在上一篇文章中,我介绍了 HeliaShare 的整体架构。今天深入探讨 Helia 的内部架构设计,以及我们如何利用这些特性构建应用。
Helia 的模块化架构
Helia 采用了高度模块化的设计,核心只包含最基本的功能,其他特性通过插件方式添加:
helia (核心)
├── @helia/unixfs - 文件系统操作
├── @helia/strings - 字符串存储
├── @helia/json - JSON 存储
├── @helia/dag-json - DAG-JSON 编码
├── @helia/ipns - 命名系统
└── @helia/car - 归档格式
核心组件解析
1. Blockstore - 块存储
Blockstore 是 Helia 的存储层,负责存储和检索 IPLD 块。
// 内存存储(开发测试用)
import { MemoryBlockstore } from 'blockstore-core'
// IndexedDB 存储(生产环境推荐)
import { IDBBlockstore } from 'blockstore-idb'
const blockstore = new MemoryBlockstore()
// 或
const blockstore = new IDBBlockstore('helia-blocks')
我们的选择: 默认使用内存存储,简化部署,但数据会在页面刷新后丢失。生产环境建议使用 IndexedDB。
2. UnixFS - 文件系统层
UnixFS 提供了类 Unix 文件系统的接口,是我们最常用的模块:
import { unixfs } from '@helia/unixfs'
const fs = unixfs(helia)
// 添加文件
const cid = await fs.addBytes(uint8Array)
// 读取文件
for await (const chunk of fs.cat(cid)) {
// 处理数据块
}
// 获取文件状态
const stat = await fs.stat(cid)
console.log(stat.size) // 文件大小
关键特性:
- 自动分块:大文件会被分割成多个块
- 自动构建 DAG:创建 Merkle DAG 结构
- 流式处理:支持大文件的流式读写
3. libp2p - 网络层
libp2p 是 Helia 的网络传输层,负责节点发现和数据传输:
helia.libp2p.peerId // 本节点 ID
helia.libp2p.getPeers() // 获取连接的对等节点
helia.libp2p.dial(addr) // 连接到指定节点
传输协议:
- WebRTC-direct: 浏览器间直接连接
- WebSocket: 通过中继服务器连接
- WebTransport: 新一代 Web 传输协议
CID 详解
CID (Content Identifier) 是 IPFS 的核心概念,理解 CID 对开发至关重要。
CID 结构
CID = [版本] + [编解码器] + [多重哈希]
CIDv0: Qm... (Base58btc, 隐式 dag-pb + sha2-256)
CIDv1: bafy... (Base32, 显式版本 + 编解码器 + 哈希)
多格式转换
import { CID } from 'multiformats'
import { base58btc } from 'multiformats/bases/base58'
import { base32 } from 'multiformats/bases/base32'
const cid = CID.parse('Qm...')
// 不同编码
cid.toString() // 默认编码
cid.toString(base58btc) // Base58 (Qm...)
cid.toString(base32) // Base32 (bafy...)
// CIDv0 vs CIDv1
const cidv0 = CID.createV0(cid.multihash) // Qm...
const cidv1 = CID.createV1(0x70, cid.multihash) // bafy...
固定机制 (Pinning)
IPFS 使用垃圾回收机制管理存储空间,只有被"固定"的数据才不会被删除。
// 固定 CID
await helia.pins.add(cid)
// 递归固定(固定整个 DAG)
await helia.pins.add(cid, { recursive: true })
// 取消固定
await helia.pins.rm(cid)
// 列出所有固定
for await (const pin of helia.pins.ls()) {
console.log(pin.cid)
}
HeliaShare 的策略: 上传和获取的文件自动固定,确保数据持久化。
内容路由
Helia 使用 DHT (分布式哈希表) 来发现内容提供者:
// 查找提供某 CID 的节点
for await (const provider of helia.libp2p.contentRouting.findProviders(cid)) {
console.log('提供者:', provider.id.toString())
console.log('地址:', provider.multiaddrs)
}
优化策略: 在 HeliaShare 中,我们配置了默认引导节点,优先从这些节点获取数据,减少 DHT 查找时间。
下一篇预告
下一篇文章将详细介绍 HeliaShare 的 UI 设计和交互实现,包括:
你对 Helia 的哪个部分最感兴趣?欢迎在评论区讨论。