基于 SPDK NVMe 与 RDMA 数据面的全闪高性能通用 Chunk 存储基础设施。
OmniChunkStore 是面向全闪 NVMe 存储场景打造的通用 Chunk 存储系统,以 SPDK NVMe 和 RDMA 构建高性能数据面。系统以 Chunk 作为统一的数据访问单元,通过 Monitor、Pool、PG 和 OSD 完成集群管理、数据放置与数据服务,为文件系统、对象网关、归档服务和块设备等上层系统提供可复用的存储底座。
OmniChunkStore 聚焦于 Chunk 边界内的数据读写、复制、一致性与本地持久化,不负责文件目录、对象命名、文件元数据或跨 Chunk 事务。上层系统可通过 SDK 将自身的数据模型映射到 Chunk,并根据业务需求实现文件、对象或块设备语义。
OmniChunkStore 的数据面能力基于开源项目 FastBlock 演进而来,并在此基础上重新设计和组织了代码结构、通信协议、SDK、部署方案与测试体系。
架构图只描述系统整体组成、控制面与数据面的关系;具体能力状态以当前状态为准。
| 组件 | 职责 | 主要技术 |
|---|---|---|
| Monitor | 集群视图、OSD 状态、Pool/PG 放置和 Leader 路由 | Go、gRPC、Protobuf、etcd |
| ChunkServer / OSD | Chunk 读写、PG 一致性、复制和故障恢复 | C++、Multi-Raft、Protobuf RPC |
| LocalStore | 将已提交数据映射到本地存储空间 | SPDK NVMe bdev;开发环境支持 io_uring 文件后端 |
| SDK | 为上层服务提供 Chunk 访问和路由能力 | Go SDK |
| Deploy | 提供可复现的开发、测试和集群编排环境 | Docker Compose |
OmniChunkStore 的高性能数据面围绕两条核心路径构建:RDMA 用户态网络传输,以及 SPDK NVMe 用户态本地 I/O。
参见高性能数据面说明,了解三节点数据路径以及 RDMA、SPDK 如何绕过通用内核网络和存储路径。
| 层次 | 设计 | 作用 |
|---|---|---|
| 数据接口 | Chunk-oriented API | 缩短请求路径,避免把文件系统语义耦合到 OSD |
| 放置与并发 | Pool / PG 分片 | 让不同 PG 并行承载请求,隔离放置和数据路径 |
| 本地 I/O | SPDK Reactor polling + SPDK NVMe bdev + QPair | Reactor 主动轮询 I/O 完成,使用用户态 I/O 路径直接访问 NVMe,绕过通用内核存储栈 |
| 网络数据面 | RDMA verbs + NIC;Protobuf RPC over RDMA;TCP/IP 作为通用传输路径 | 使用低延迟用户态网络连接 OSD,绕过通用内核 TCP/IP 路径,并保留通用传输能力 |
| 性能定位 | Metrics、Trace、pprof、perf、eBPF | 分层定位 Monitor、网络、Raft、SPDK 和设备 I/O 瓶颈 |
开发/验证环境与高性能部署的区别:
| 模式 | 网络 | 本地存储 |
|---|---|---|
| 开发/验证 | TCP/IP | SPDK uring(io_uring)文件后端 |
| 高性能部署 | RDMA(可保留 TCP/IP) | SPDK NVMe bdev + 真实 NVMe |
RDMA 负责节点间数据面通信,SPDK NVMe 负责 OSD 本地 I/O;两者共同构成全闪数据面,也可以分别调优。开发/验证环境使用软件后端和 TCP/IP 以保证可复现,不代表生产部署的真实 RDMA 网卡和 NVMe 路径。
逻辑模型描述数据如何组织和放置:
Cluster
└── Pool 存储策略
└── PG 放置、复制和一致性单元
└── Chunk 逻辑数据单元
运行时模型描述数据由哪些进程和本地资源承载:
Node
└── ChunkServer 进程
└── OSD 实例
├── PG 1
├── PG 2
└── LocalStore
└── 存储后端
├── SPDK NVMe bdev → NVMe namespace
└── io_uring 文件(开发/验证)
当前部署中,一个 ChunkServer 进程承载一个 OSD 实例;一个 OSD 可以承载多个 PG,并绑定一个配置好的本地存储后端。OSD 是提供数据服务的进程/实例,不等同于 NVMe SSD:生产环境通常通过 SPDK NVMe bdev 对接 NVMe namespace,开发/验证环境则使用 io_uring 文件后端。
默认逻辑 Chunk 大小为 4 MiB。它是 OmniChunkStore 与上层适配器之间的语义边界,不等同于 NVMe 物理块大小,也不要求每次底层 I/O 都是 4 MiB。
开发/验证环境使用 TCP/IP 和 SPDK uring(io_uring)文件后端;高性能部署使用数据面 RDMA 和 SPDK NVMe bdev 对接真实 NVMe。
Pool 由两个独立维度组成:Chunk 是否允许覆盖更新,以及数据采用副本还是纠删码保护。
| 策略 | 更新语义 | 数据保护与一致性 |
|---|---|---|
MUTABLE_R3 |
允许覆盖写和随机写 | 3 副本;Multi-Raft 负责更新顺序、复制和提交 |
IMMUTABLE_R3 |
Chunk Seal 后不可覆盖,更新创建新版本 | 3 副本;采用 seal-and-new,不为每次更新进入 Multi-Raft |
MUTABLE_EC42 |
允许覆盖写,通过版本化 COW 生成新数据 | 4+2 纠删码;Multi-Raft 负责逻辑更新顺序,EC 负责数据保护 |
IMMUTABLE_EC42 |
Chunk Seal 后不可覆盖,新数据写入新版本 | 4+2 纠删码;采用 seal-and-new,避免不可变数据的逐次 Raft 更新 |
当前实现重点是 MUTABLE_R3、PG/Multi-Raft 和基础 Chunk I/O;EC 与 Immutable 路径属于后续演进能力。
| 能力 | 状态 |
|---|---|
| Monitor 控制面和 OSD 注册 | 可用 |
| Chunk 基础读写和删除 | 可用 |
| PG / Multi-Raft 三副本路径 | 可用 |
| Go SDK | 可用 |
| Docker 三 Monitor + 三 OSD 环境 | 可用 |
SPDK uring 本地 I/O 后端 |
可用 |
| Prometheus / OpenTelemetry 观测能力 | 持续完善 |
| Erasure Coding、Immutable Pool | 演进中 |
| RDMA、SPDK NVMe 和真实 NVMe 部署 | 实验性 |
在仓库根目录执行:
# 构建协议和项目
make build
# 运行单元测试
make unit
# 启动开发/验证集群
docker compose -f deploy/docker/compose/runtime.yml up -d \
omnistore-monitor-1 omnistore-monitor-2 omnistore-monitor-3 \
omnistore-osd-1 omnistore-osd-2 omnistore-osd-3停止开发集群:
docker compose -f deploy/docker/compose/runtime.yml down当前已经支持通过 JuiceFS 访问 OmniChunkStore。想快速体验基于 OmniChunkStore 的 JuiceFS 文件系统,可以直接执行:
make juicefs该命令会启动三节点 Monitor、三节点 OSD、Redis 和 JuiceFS 客户端,自动创建
默认 Pool 和文件系统。按照命令输出进入 juicefs-client 容器后,在
/mnt/juicefs 下读写文件。这个 Demo 用于本地体验,不是生产部署方案;停止
环境但保留数据可执行:
docker compose -p omnichunkstore-juicefs-demo \
-f deploy/docker/compose/runtime.yml \
-f deploy/docker/compose/juicefs.yml downmake unit # C++、Monitor 和 Go SDK 单元测试
make integration-omnistore # OmniChunkStore 集成测试
make integration-juicefs # JuiceFS 集成测试
make integration # 运行全部集成测试
make performance # JuiceFS 性能测试
make performance-rados # RADOS 对照测试集成测试和性能测试使用 Docker 环境。性能结果必须同时记录硬件、容器拓扑、PG 数量、副本策略和测试命令,才能进行有效比较。
OmniChunkStore/
├── api/proto/ # 跨组件共享的 Protobuf 源文件
│ ├── monitor/ # Monitor 公共协议
│ └── chunkserver/ # ChunkServer 公共协议
├── cmd/
│ ├── monitor/ # Monitor 可执行程序入口
│ ├── chunkserver/ # ChunkServer/OSD 可执行程序入口
│ └── admin/ # 管理命令行工具
├── src/
│ ├── monitor/ # Go 控制面服务实现
│ └── chunkserver/ # C++ 数据面服务实现
│ ├── osd/ # OSD 生命周期和请求处理
│ ├── raftgroup/ # PG 一致性与复制
│ ├── localstore/ # 本地持久化
│ ├── transport/ # RPC、TCP/RDMA 传输和私有协议
│ ├── runtime/ # SPDK 分片和 Reactor 运行时
│ ├── monitor_client/ # ChunkServer 到 Monitor 的客户端
│ ├── config/ # 配置解析与校验
│ ├── log/ # 日志配置
│ └── observability/ # C++ Metrics 和 Trace
├── sdk/go/ # Go Chunk SDK
├── deploy/ # 部署清单、配置和镜像
├── tests/ # 单元、集成、故障恢复和性能测试
├── observability/ # Metrics、Trace 和 Profiling 工具配置
└── docs/ # 暂存的架构图和设计材料
OmniChunkStore 使用 MulanPSL-2.0 许可证。项目中基于 FastBlock 改造的部分保留原始许可证和版权声明。


