SPDK整体架构分析文档
1. SPDK概述
1.1 什么是SPDK
SPDK(Storage Performance Development Kit)是Intel开发的高性能存储开发工具包,旨在提供用户态、轮询模式(Polling Mode)的存储应用开发框架。
1.2 核心设计理念
- 用户态驱动:将所有必要的驱动程序移到用户空间,避免内核上下文切换
- 轮询模式:使用轮询而非中断,消除中断处理开销
- 零拷贝:最小化数据拷贝操作
- NUMA感知:支持NUMA架构的内存和CPU管理
- 事件驱动:基于事件驱动的异步I/O模型
2. SPDK整体架构
2.1 架构层次
1 | ┌─────────────────────────────────────────────────────────┐ |
2.2 目录结构
1 | spdk/ |
3. SPDK核心模块详解
3.1 环境抽象层 (env_dpdk)
位置: lib/env_dpdk/
功能: SPDK与DPDK之间的抽象层,封装DPDK功能为SPDK接口
主要文件:
init.c: DPDK EAL初始化memory.c: 内存管理(基于DPDK hugepages)threads.c: 线程管理(基于DPDK lcore)pci.c: PCI设备管理(基于DPDK PCI bus)env.c: 环境抽象接口实现
关键功能:
- DPDK EAL初始化封装
- 大页内存管理
- NUMA感知的内存分配
- 线程/核心管理
- PCI设备发现和绑定
3.2 块设备抽象层 (BDEV)
位置: lib/bdev/
功能: 提供统一的块设备抽象接口,支持多种后端存储
核心概念:
- BDEV: 块设备抽象,提供统一的I/O接口
- BDEV模块: 实现具体存储后端的模块
- BDEV栈: 支持BDEV的叠加(如加密、压缩、RAID等)
支持的BDEV类型:
- NVMe BDEV
- Malloc BDEV(内存)
- AIO BDEV(Linux异步I/O)
- PMEM BDEV(持久化内存)
- Virtio BDEV
- iSCSI Initiator BDEV
- RBD BDEV(Ceph)
- Lvol BDEV(逻辑卷)
- RAID BDEV
- 等等
3.3 NVMe驱动 (nvme)
位置: lib/nvme/
功能: 用户态NVMe驱动实现
主要组件:
- NVMe控制器管理:
nvme_ctrlr.c - 命名空间管理:
nvme_ns.c - 队列对管理:
nvme_qpair.c - PCIe传输:
nvme_pcie.c - RDMA传输:
nvme_rdma.c - TCP传输:
nvme_tcp.c - Fabric传输:
nvme_fabric.c
特性:
- 支持NVMe 1.3/1.4规范
- 支持OCSSD(Open Channel SSD)
- 支持Opal安全功能
- 支持热插拔
- 支持多路径
3.4 SCSI子系统 (scsi)
位置: lib/scsi/
功能: SCSI协议实现,用于iSCSI Target
主要组件:
- SCSI设备管理
- SCSI LUN管理
- SCSI端口管理
- SCSI任务处理
- SCSI持久保留(PR)
3.5 Vhost子系统 (vhost)
位置: lib/vhost/
功能: 实现Vhost协议,支持QEMU/KVM虚拟化
特性:
- Vhost SCSI
- Vhost Blk
- Vhost User协议
- 与QEMU集成
3.6 Blob存储 (blob)
位置: lib/blob/
功能: 提供对象存储抽象,支持元数据管理
核心概念:
- Blobstore: 底层存储管理器
- Blob: 可变大小的对象
- Cluster: 存储单元
- Page: 元数据页
3.7 BlobFS (blobfs)
位置: lib/blobfs/
功能: 在Blobstore上实现POSIX兼容的文件系统
特性:
- POSIX API兼容
- FUSE支持
- 高性能元数据操作
3.8 加速引擎 (accel)
位置: lib/accel/
功能: 提供硬件加速抽象,支持IOAT、IDXD等
支持的加速器:
- IOAT(Intel I/O Acceleration Technology)
- IDXD(Intel Data Streaming Accelerator)
3.9 事件框架 (event)
位置: module/event/
功能: 提供事件驱动的编程模型
核心组件:
- 事件子系统管理
- Reactor模式实现
- 线程调度
- 应用生命周期管理
4. SPDK与DPDK的集成关系
4.1 DPDK在SPDK中的作用
SPDK使用DPDK作为底层环境抽象层,主要利用DPDK的以下功能:
4.1.1 DPDK EAL (Environment Abstraction Layer)
使用位置: lib/env_dpdk/init.c
功能:
- 系统初始化
- 大页内存管理
- CPU核心管理
- 设备发现
关键调用:
1 | rte_eal_init() // 初始化EAL |
4.1.2 DPDK内存管理
使用位置: lib/env_dpdk/memory.c, lib/env_dpdk/env.c
使用的DPDK模块:
librte_malloc: 内存分配librte_mempool: 内存池librte_memzone: 内存区域librte_memory: 内存配置
关键API:
1 | rte_malloc_socket() // NUMA感知的内存分配 |
4.1.3 DPDK线程/核心管理
使用位置: lib/env_dpdk/threads.c
使用的DPDK模块:
librte_lcore: 逻辑核心管理
关键API:
1 | rte_lcore_count() // 获取核心数量 |
4.1.4 DPDK PCI设备管理
使用位置: lib/env_dpdk/pci.c
使用的DPDK模块:
librte_bus_pci: PCI总线librte_pci: PCI设备librte_dev: 设备管理
关键API:
1 | rte_pci_read_config() // 读取PCI配置空间 |
4.1.5 DPDK VFIO支持
使用位置: lib/env_dpdk/memory.c, lib/env_dpdk/init.c
使用的DPDK模块:
librte_vfio: VFIO支持
关键API:
1 | rte_vfio_enable() // 启用VFIO |
4.1.6 DPDK告警机制
使用位置: lib/env_dpdk/pci.c
使用的DPDK模块:
librte_alarm: 告警/定时器
关键API:
1 | rte_eal_alarm_set() // 设置告警 |
4.2 SPDK对DPDK的封装
SPDK通过env_dpdk模块将DPDK功能封装为统一的SPDK接口:
4.2.1 内存管理封装
1 | // SPDK接口 |
4.2.2 线程管理封装
1 | // SPDK接口 |
4.2.3 环境初始化封装
1 | // SPDK接口 |
4.3 DPDK模块使用总结
| DPDK模块 | SPDK使用位置 | 主要功能 |
|---|---|---|
librte_eal |
env_dpdk/init.c |
EAL初始化、系统配置 |
librte_malloc |
env_dpdk/env.c |
内存分配 |
librte_mempool |
env_dpdk/env.c |
内存池管理 |
librte_memzone |
env_dpdk/env.c |
内存区域管理 |
librte_memory |
env_dpdk/memory.c |
内存配置 |
librte_lcore |
env_dpdk/threads.c |
逻辑核心管理 |
librte_bus_pci |
env_dpdk/pci.c |
PCI总线 |
librte_pci |
env_dpdk/pci.c |
PCI设备操作 |
librte_dev |
env_dpdk/pci.c |
设备管理 |
librte_vfio |
env_dpdk/memory.c, env_dpdk/init.c |
VFIO支持 |
librte_alarm |
env_dpdk/pci.c |
告警/定时器 |
librte_cycles |
env_dpdk/env.c |
时间戳/周期计数 |
5. SPDK应用模式
5.1 SPDK Target (spdk_tgt)
位置: app/spdk_tgt/
功能: 通用的SPDK目标应用,支持多种存储协议
特性:
- 支持BDEV管理
- 支持NVMe over Fabrics Target
- 支持iSCSI Target
- 支持Vhost
- JSON-RPC接口
5.2 NVMe over Fabrics Target (nvmf_tgt)
位置: app/nvmf_tgt/
功能: 专门的NVMe over Fabrics目标应用
支持的传输:
- RDMA
- TCP
- FC(Fibre Channel)
5.3 Vhost Target (vhost)
位置: app/vhost/
功能: Vhost目标应用,用于虚拟化场景
特性:
- 与QEMU集成
- 支持Vhost SCSI和Vhost Blk
6. SPDK模块系统
6.1 模块注册机制
SPDK使用模块注册机制实现插件化架构:
1 | // BDEV模块注册 |
6.2 主要模块类型
6.2.1 BDEV模块
位置: module/bdev/
主要模块:
nvme: NVMe BDEVmalloc: 内存BDEVaio: AIO BDEVpmem: PMEM BDEVvirtio: Virtio BDEVlvol: 逻辑卷BDEVraid: RAID BDEVcompress: 压缩BDEVcrypto: 加密BDEVocf: OCF缓存BDEV- 等等
6.2.2 Accel模块
位置: module/accel/
主要模块:
ioat: IOAT加速idxd: IDXD加速
6.2.3 Socket模块
位置: module/sock/
主要模块:
posix: POSIX Socketuring: io_uring Socketvpp: VPP Socket
7. SPDK初始化流程
7.1 典型初始化序列
1 | 1. spdk_env_init() |
8. SPDK性能优化特性
8.1 轮询模式
- 不使用中断,避免上下文切换
- 主动轮询设备完成队列
- 零延迟响应
8.2 零拷贝
- 直接内存访问(DMA)
- 避免不必要的内存拷贝
- 使用大页内存减少TLB缺失
8.3 NUMA感知
- 内存分配考虑NUMA节点
- CPU核心绑定到NUMA节点
- 减少跨NUMA访问
8.4 无锁设计
- 使用无锁数据结构
- 每核心数据结构
- 减少锁竞争
9. 总结
SPDK是一个高性能的存储开发框架,其核心优势在于:
- 用户态驱动: 避免内核上下文切换
- 轮询模式: 消除中断开销
- 模块化设计: 易于扩展和维护
- DPDK集成: 充分利用DPDK的底层能力
- 事件驱动: 高效的异步I/O模型
SPDK通过env_dpdk模块将DPDK的功能封装为统一的接口,主要使用DPDK的以下模块:
- EAL(环境抽象层)
- 内存管理(malloc、mempool、memzone)
- 线程/核心管理(lcore)
- PCI设备管理(bus_pci、pci)
- VFIO支持
- 告警机制
这种设计使得SPDK既能充分利用DPDK的底层能力,又能保持接口的统一性和可移植性。
正在加载留言…