导语:在这个数据被巨头垄断的时代,有没有一种数据库能让你的数据真正属于自己?OrbitDB 给出了一个大胆的答案——一个无需服务器、无需云厂商、甚至无需联网就能运行的去中心化数据库。本文将带你深入理解这个 8.7k Star 的开源项目。
OrbitDB 是一个无服务器、分布式、点对点数据库,专为去中心化网络设计。它由 Protocol Labs(也是 IPFS 的缔造者)支持开发,目前在 GitHub 上拥有 8.7k Stars 和 591 Forks。
| 特性 | 说明 |
|---|---|
| **无服务器** | 不需要中心化服务器,每个节点都是服务器 |
| **P2P 同步** | 通过 Libp2p Pubsub 自动与对等节点同步数据 |
| **最终一致性** | 使用 Merkle-CRDTs 实现无冲突的数据写入和合并 |
| **离线优先** | 断网也能正常使用,联网后自动同步 |
| **密码学验证** | 所有操作都可被密码学验证,不可篡改 |
OrbitDB = IPFS(存储层) + Libp2p(网络层) + Merkle-CRDT(一致性层)
传统架构:客户端 → 中心服务器 → 数据库(单点故障 + 数据垄断)
OrbitDB 架构:节点 A ↔ P2P 网络 ↔ 节点 B,各自存储在 IPFS 上(无服务器 + 数据自主 + 抗审查)
OrbitDB 使用 IPFS 作为底层存储。IPFS 是一种内容寻址的分布式文件系统:
这是 OrbitDB 的核心黑科技。CRDT(Conflict-free Replicated Data Type)允许:
// 示例:两个节点同时添加数据
节点 A: db.add('Hello')
节点 B: db.add('World')
// 同步后,两个节点都能看到
['Hello', 'World'] // 自动合并,无冲突!
所有数据库都构建在 OpLog 之上:
OrbitDB 提供了四种数据库类型,满足不同场景:
不可变的追加日志,适合消息队列、时间线等场景。
const db = await orbitdb.open('my-log', { type: 'events' })
await db.add({ text: '第一条消息', timestamp: Date.now() })
await db.add({ text: '第二条消息', timestamp: Date.now() })
// 获取最新 10 条
const latest = await db.iterator({ limit: 10 }).collect()
存储 JSON 文档,支持按指定键索引,类似 MongoDB。
const db = await orbitdb.open('my-docs', { type: 'documents' })
// 存储文档
await db.put({ _id: 'user1', name: 'Alice', age: 25 })
await db.put({ _id: 'user2', name: 'Bob', age: 30 })
// 查询
const user = await db.get('user1')
const adults = await db.query((doc) => doc.age >= 18)
经典的键值数据库,类似 Redis。
const db = await orbitdb.open('my-kv', { type: 'keyvalue' })
await db.set('username', 'alice')
await db.set('settings', { theme: 'dark', lang: 'zh' })
const username = await db.get('username') // 'alice'
在 LevelDB 中建立索引的键值数据库,适合大规模数据。
npm install @orbitdb/core helia
import { createHelia } from 'helia'
import { createOrbitDB } from '@orbitdb/core'
import { gossipsub } from '@chainsafe/libp2p-gossipsub'
import { identify } from '@libp2p/identify'
import { createLibp2p } from 'libp2p'
// 配置 Libp2p
const libp2p = await createLibp2p({
services: {
pubsub: gossipsub({ allowPublishToZeroTopicPeers: true }),
identify: identify()
}
})
// 创建 IPFS 实例
const ipfs = await createHelia({ libp2p })
// 创建 OrbitDB 实例
const orbitdb = await createOrbitDB({ ipfs })
// 打开/创建数据库(默认 events 类型)
const db = await orbitdb.open('hello-world')
console.log(db.address)
// /orbitdb/zdpuAkstgbTVGHQmMi5TC84auhJ8rL5qoaNEtXo2d5PHXs2To
// 这个地址可以在其他节点上使用,打开同一个数据库
// 监听来自其他节点的更新
db.events.on('update', async (entry) => {
console.log('收到新数据:', entry.payload.value)
const all = await db.all()
console.log('当前所有数据:', all)
})
// 添加数据
const hash = await db.add('Hello from Alice!')
// 查询数据
for await (const record of db.iterator()) {
console.log(record.payload.value)
}
每个用户有自己的数据库:
类似 Google Docs,但无需中心服务器:
// 记录产品流转
await db.add({
productId: 'PROD-001',
event: '生产完成',
location: '工厂A',
timestamp: Date.now(),
signature: '...' // 数字签名
})
数据首先存储在本地,联网后自动同步:
OrbitDB 与传统数据库的设计哲学截然不同:
❌ 传统:所有用户的推文存在一个大数据库
tweets 表 → 数百万用户同时写入
✅ OrbitDB:每个用户有自己的数据库
alice-tweets → 只有 Alice 写入
bob-tweets → 只有 Bob 写入
关注 = 复制对方的数据库到本地
OrbitDB 不仅限于 JavaScript:
| 实现 | 项目 | 维护者 |
|---|---|---|
| Go | berty/go-orbit-db | Berty 项目 |
| Python | orbitdb/py-orbit-db-http-client | 社区 |
IPFS 是"永久"存储,但需要节点保持在线。如果所有节点都离线,数据可能丢失。
解决方案:使用 Filecoin 等激励层,或自建 pinning 服务。
相比传统数据库,复杂查询性能较弱。
解决方案:配合索引数据库(keyvalue-indexed)或外部索引服务。
P2P 网络需要解决 NAT 穿透等问题。
解决方案:使用公共 relay 节点,或配置端口转发。
OrbitDB 代表了数据库发展的一个方向:
结语:OrbitDB 不是银弹,它牺牲了部分性能和便利性,换取了数据自主和去中心化的特性。但在数据隐私日益重要的今天,这种取舍可能是值得的。毕竟,"Not your keys, not your data"。
本文撰写于 2026年2月26日,基于 OrbitDB v2.x 版本
还没有人回复