Li Sheng | Backend / Distributed Storage Engineer Li Sheng | Backend / Distributed Storage Engineer
Home
Resume
Projects
Topics
Notes
GitHub (opens new window)
Home
Resume
Projects
Topics
Notes
GitHub (opens new window)
  • Go语言

  • C++

  • 算法题

  • 存储系统

    • 导航

    • 单机IO基础

    • IO语义与持久化

    • 块层与高速路径

      • 块层与I-O调度总览
      • blk-mq多队列模型
      • 高速存储路径总览
        • 1. 为什么会出现这些技术
        • 2. NVMe 带来了什么变化
        • 3. Direct I-O 在解决什么问题
        • 4. io_uring 在解决什么问题
        • 5. SPDK 在解决什么问题
        • 6. 这几种技术不是替代关系,而是路径选择
        • 7. 怎么建立一个实用判断框架
        • 8. 和当前笔记的关系
        • 9. 适合继续拆开的专题
    • Ceph

    • DAOS

    • 归档

  • CephFS

  • 分布式系统

  • 计算机网络

  • Redis与缓存

  • Kubernetes

  • 技术笔记
  • 存储系统
  • 块层与高速路径
lisheng
2026-04-27
目录

高速存储路径总览

# 高速存储路径总览:NVMe、Direct I-O、io_uring、SPDK

存储设备越来越快之后,瓶颈往往不再只是“盘慢”,而是“软件路径太长”。这也是为什么后来的讨论越来越多地转向 NVMe、多队列、Direct I/O、io_uring 和 SPDK。

# 1. 为什么会出现这些技术

在传统路径里,一次 I/O 往往要经过:

  • 系统调用切换
  • VFS / 文件系统
  • Page Cache
  • 块层
  • 调度器
  • 驱动

这条路径很通用,但也很重。

当设备速度越来越高,通用路径里的每一层开销都变得更显眼,于是大家开始想办法:

  • 减少内核参与
  • 减少拷贝
  • 减少上下文切换
  • 增强并发队列利用率

# 2. NVMe 带来了什么变化

NVMe 的关键不只是“更快”,而是它天然面向高并发和低延迟:

  • 队列更多
  • 并行度更高
  • 更适合多核 CPU
  • 更容易把瓶颈暴露到软件栈

所以 NVMe 时代,性能分析的重点会从“磁盘寻道”更多转向:

  • 队列深度
  • CPU 开销
  • 中断和轮询
  • 多队列绑定
  • 用户态路径优化

# 3. Direct I-O 在解决什么问题

Direct I/O 的核心思路是:

绕过 Page Cache,尽量让数据更直接地在应用和设备之间流动。

它通常适合:

  • 应用自己管理缓存
  • 不希望双重缓存
  • 大块顺序 I/O
  • 需要更明确的 I/O 控制语义

但它不是“天然更快”,因为它也失去了缓存命中和写回合并带来的好处。

所以更准确的说法是:

Direct I/O 不是万能加速,而是把控制权交还给应用。

# 4. io_uring 在解决什么问题

io_uring 更像是在保留内核 I/O 能力的前提下,尽量把提交和完成路径做轻量化。

它的价值主要在于:

  • 减少系统调用成本
  • 改善异步 I/O 编程模型
  • 更适合高并发提交/回收
  • 为零拷贝、固定缓冲区等优化提供更好接口

可以把它理解成:

“不一定绕过内核,但尽量把内核 I/O 的路径做得更薄。”

# 5. SPDK 在解决什么问题

SPDK 的思路比 io_uring 更激进:

它把很多 I/O 处理放到用户态,尽量绕过传统内核块层和调度路径,直接驱动 NVMe 等高性能设备。

典型收益:

  • 更低延迟
  • 更少上下文切换
  • 更强的 CPU 亲和和轮询控制
  • 更适合极致性能场景

代价也很明确:

  • 编程和运维复杂度更高
  • 通用性变差
  • 需要系统设计者自己承担更多资源管理责任

# 6. 这几种技术不是替代关系,而是路径选择

更适合把它们看成不同层次的选择:

  • Page Cache:默认通用路径,适合大多数文件 I/O
  • Direct I/O:绕过缓存,但仍走内核设备路径
  • io_uring:优化内核 I/O 提交与完成路径
  • SPDK:更激进的用户态设备访问路径

而 NVMe 是促使这些路径优化越来越重要的硬件背景。

# 7. 怎么建立一个实用判断框架

看一个系统时,可以先问这几个问题:

  1. 设备快到什么程度了?
  2. 瓶颈在设备、内核路径还是应用逻辑?
  3. 应用是否愿意自己管理缓存?
  4. 更看重通用性,还是极致性能?
  5. 是想优化接口成本,还是直接重构整条 I/O 路径?

这几个问题能帮助你判断应该继续走内核默认路径,还是转向更“贴设备”的方案。

# 8. 和当前笔记的关系

  • 基础缓存层:Page Cache总览
  • 语义层补充:fsync、写回与刷盘语义
  • 恢复语义补充:文件系统日志与崩溃恢复
  • 块层视角:块层与I-O调度总览
  • 多队列衔接:blk-mq多队列模型
  • DAOS 相关依赖:SPDK Blob
  • 总入口:技术专题

# 9. 适合继续拆开的专题

  • 61.NVMe队列模型
  • 62.Direct I-O适用场景
  • 63.io_uring提交与完成路径
  • 64.SPDK轮询模型

关联文章

匹配标签:NVMe, Direct I/O, io_uring, SPDK

  • blk-mq多队列模型
Edit (opens new window)
Last Updated: 2026/04/28, 15:19:51
blk-mq多队列模型
Ceph架构设计

← blk-mq多队列模型 Ceph架构设计→

最近更新
01
待完成专题池
04-28
02
待完成专题池
04-28
03
为什么 Kubernetes CSI 插件架构要拆成 Controller、Node 与 Sidecar
04-28
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式