SPDK整体架构分析文档

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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
┌─────────────────────────────────────────────────────────┐
│ 应用程序层 (Applications) │
│ (spdk_tgt, nvmf_tgt, vhost, iscsi_tgt等) │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│ 子系统层 (Subsystems) │
│ (BDEV, NVMe, SCSI, Vhost, iSCSI, NVMf等) │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│ 模块层 (Modules) │
│ (BDEV模块、Accel模块、Blob模块、BlobFS模块等) │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│ 核心库层 (Core Libraries) │
│ (NVMe驱动、BDEV抽象、SCSI、Virtio、Vhost等) │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│ 环境抽象层 (Environment Abstraction) │
│ (env_dpdk: DPDK环境封装) │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│ DPDK层 (DPDK Framework) │
│ (EAL、内存管理、PCI设备管理、线程管理等) │
└─────────────────────────────────────────────────────────┘

2.2 目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
spdk/
├── app/ # 应用程序
│ ├── spdk_tgt/ # SPDK通用目标应用
│ ├── nvmf_tgt/ # NVMe over Fabrics目标应用
│ └── vhost/ # Vhost目标应用
├── lib/ # 核心库
│ ├── env_dpdk/ # DPDK环境抽象层
│ ├── bdev/ # 块设备抽象层
│ ├── nvme/ # NVMe驱动
│ ├── scsi/ # SCSI协议实现
│ ├── vhost/ # Vhost实现
│ ├── virtio/ # Virtio驱动
│ ├── blob/ # Blob存储
│ ├── blobfs/ # Blob文件系统
│ ├── accel/ # 加速引擎
│ ├── rdma/ # RDMA支持
│ └── util/ # 工具函数
├── module/ # 模块实现
│ ├── bdev/ # BDEV模块
│ ├── accel/ # 加速模块
│ ├── blob/ # Blob模块
│ ├── blobfs/ # BlobFS模块
│ ├── event/ # 事件子系统
│ └── sock/ # Socket抽象
├── include/ # 头文件
├── examples/ # 示例代码
└── dpdk/ # DPDK子模块

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
2
3
rte_eal_init()              // 初始化EAL
rte_eal_hotplug_add() // 热插拔添加设备
rte_eal_hotplug_remove() // 热插拔移除设备

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
2
3
4
rte_malloc_socket()         // NUMA感知的内存分配
rte_malloc_virt2iova() // 虚拟地址到IOVA转换
rte_mempool_create() // 创建内存池
rte_memzone_reserve() // 保留内存区域

4.1.3 DPDK线程/核心管理

使用位置: lib/env_dpdk/threads.c

使用的DPDK模块:

  • librte_lcore: 逻辑核心管理

关键API:

1
2
3
4
5
6
rte_lcore_count()           // 获取核心数量
rte_lcore_id() // 获取当前核心ID
rte_lcore_to_socket_id() // 核心到NUMA节点映射
rte_eal_remote_launch() // 在指定核心启动函数
rte_eal_mp_wait_lcore() // 等待所有核心完成
rte_get_next_lcore() // 获取下一个核心

4.1.4 DPDK PCI设备管理

使用位置: lib/env_dpdk/pci.c

使用的DPDK模块:

  • librte_bus_pci: PCI总线
  • librte_pci: PCI设备
  • librte_dev: 设备管理

关键API:

1
2
3
4
5
6
rte_pci_read_config()       // 读取PCI配置空间
rte_pci_write_config() // 写入PCI配置空间
rte_eal_hotplug_add() // 热插拔添加
rte_eal_hotplug_remove() // 热插拔移除
rte_dev_probe() // 探测设备
rte_dev_remove() // 移除设备

4.1.5 DPDK VFIO支持

使用位置: lib/env_dpdk/memory.c, lib/env_dpdk/init.c

使用的DPDK模块:

  • librte_vfio: VFIO支持

关键API:

1
2
rte_vfio_enable()           // 启用VFIO
rte_vfio_setup_device() // 设置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
2
3
4
5
6
7
8
9
10
// SPDK接口
void *spdk_malloc(size_t size, size_t align, uint64_t *phys_addr,
int socket_id, uint32_t flags);
void *spdk_zmalloc(...);
void spdk_free(void *buf);

// 内部实现(基于DPDK)
rte_malloc_socket()
rte_malloc_virt2iova()
rte_free()

4.2.2 线程管理封装

1
2
3
4
5
6
7
8
9
10
11
12
// SPDK接口
uint32_t spdk_env_get_core_count(void);
uint32_t spdk_env_get_current_core(void);
int spdk_env_thread_launch_pinned(uint32_t core,
thread_start_fn fn, void *arg);
void spdk_env_thread_wait_all(void);

// 内部实现(基于DPDK)
rte_lcore_count()
rte_lcore_id()
rte_eal_remote_launch()
rte_eal_mp_wait_lcore()

4.2.3 环境初始化封装

1
2
3
4
5
// SPDK接口
int spdk_env_init(const struct spdk_env_opts *opts);

// 内部实现(基于DPDK)
rte_eal_init()

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
2
3
4
5
// BDEV模块注册
SPDK_BDEV_MODULE_REGISTER(module_name, module_init_fn, module_fini_fn)

// Accel模块注册
SPDK_ACCEL_MODULE_REGISTER(module_name, module_init_fn, module_fini_fn)

6.2 主要模块类型

6.2.1 BDEV模块

位置: module/bdev/

主要模块:

  • nvme: NVMe BDEV
  • malloc: 内存BDEV
  • aio: AIO BDEV
  • pmem: PMEM BDEV
  • virtio: Virtio BDEV
  • lvol: 逻辑卷BDEV
  • raid: RAID BDEV
  • compress: 压缩BDEV
  • crypto: 加密BDEV
  • ocf: OCF缓存BDEV
  • 等等

6.2.2 Accel模块

位置: module/accel/

主要模块:

  • ioat: IOAT加速
  • idxd: IDXD加速

6.2.3 Socket模块

位置: module/sock/

主要模块:

  • posix: POSIX Socket
  • uring: io_uring Socket
  • vpp: VPP Socket

7. SPDK初始化流程

7.1 典型初始化序列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1. spdk_env_init()
└─> rte_eal_init() // 初始化DPDK EAL
├─> 大页内存分配
├─> CPU核心检测
└─> PCI设备扫描

2. spdk_app_start()
└─> 事件框架初始化
├─> Reactor创建
└─> 子系统初始化

3. 子系统初始化
├─> BDEV子系统
├─> NVMe子系统
├─> SCSI子系统
└─> 其他子系统

4. 模块加载
├─> BDEV模块加载
├─> Accel模块加载
└─> 其他模块加载

5. 应用启动
└─> 开始事件循环

8. SPDK性能优化特性

8.1 轮询模式

  • 不使用中断,避免上下文切换
  • 主动轮询设备完成队列
  • 零延迟响应

8.2 零拷贝

  • 直接内存访问(DMA)
  • 避免不必要的内存拷贝
  • 使用大页内存减少TLB缺失

8.3 NUMA感知

  • 内存分配考虑NUMA节点
  • CPU核心绑定到NUMA节点
  • 减少跨NUMA访问

8.4 无锁设计

  • 使用无锁数据结构
  • 每核心数据结构
  • 减少锁竞争

9. 总结

SPDK是一个高性能的存储开发框架,其核心优势在于:

  1. 用户态驱动: 避免内核上下文切换
  2. 轮询模式: 消除中断开销
  3. 模块化设计: 易于扩展和维护
  4. DPDK集成: 充分利用DPDK的底层能力
  5. 事件驱动: 高效的异步I/O模型

SPDK通过env_dpdk模块将DPDK的功能封装为统一的接口,主要使用DPDK的以下模块:

  • EAL(环境抽象层)
  • 内存管理(malloc、mempool、memzone)
  • 线程/核心管理(lcore)
  • PCI设备管理(bus_pci、pci)
  • VFIO支持
  • 告警机制

这种设计使得SPDK既能充分利用DPDK的底层能力,又能保持接口的统一性和可移植性。

文章互动

阅读 --

留言

0 条留言

正在加载留言…