一份数据从 CPU 寄存器到磁带库,访问延迟横跨十几个数量级:最快的不到 1 纳秒,最慢的要几分钟。存储这门学问,说到底就是在这条"速度—容量—价格—是否易失"的光谱上做取舍,并把取舍的结果组织成一个可靠的系统。
这一课先建立两张"全景图":一张是存储层次与延迟数量级,让你对"多快算快、多慢算慢"有直觉;另一张是 DAS、SAN、NAS、对象存储、分布式存储这几种接入方式,让你知道数据可以"住"在哪里、以什么方式被访问。最后我们聊聊存储工程师每天到底在干什么。
为什么会有"存储层次"
理想的存储应该又快、又大、又便宜、断电不丢。现实是这四个属性两两打架:
- 快的贵:SRAM 做的 CPU 缓存每 GB 的成本是 DRAM 的上百倍,所以一颗 CPU 只有几十 MB 的 L3。
- 大的慢:一块 24 TB 的机械盘每 GB 不到一毛钱,但随机读一次要 8 ms 左右。
- 快的易失:寄存器、缓存、内存断电即失;要持久化,就得落到 NAND 闪存或磁介质上,而它们慢了两到五个数量级。
于是计算机的做法是分层:把最常用的数据放在又小又快的层,把全部数据放在又大又慢的层,中间用缓存、预读、回写把它们粘起来。你后面会学到的页缓存(Page Cache)、SSD 内部的 DRAM 缓存、RAID 卡的写缓存、Ceph 的 BlueStore 缓存,全是同一个思路在不同层次上的重复。
▲ 更快、更贵、更小、易失
│ 寄存器 ~ 几百 B / 核
│ L1/L2/L3 缓存 ~ KB ~ 百 MB
│ DRAM 内存 ~ GB ~ TB
易失 ────┼──────────────────────────────── 持久化分界线
│ NVMe / SATA SSD ~ TB / 盘
│ HDD 机械盘 ~ 10~30 TB / 盘
│ 网络存储 / 分布式存储 / 对象存储 ~ PB ~ EB
│ 磁带 / 冷归档
▼ 更慢、更便宜、更大、持久中间那条"持久化分界线"是整个课程最重要的一条线。线以上的数据,断电就没了;线以下的才算"存下来"。应用调用 write() 返回成功时,数据往往还在线以上——这就是阶段 1 页缓存与持久化语义要专门讲的问题。
延迟数量级:你必须有的直觉
Brendan Gregg 在《Systems Performance》第 2 章给过一张很有名的表:把 1 个 CPU 周期(约 0.3 ns)放大成 1 秒,其他操作按同样比例放大,人类就能直观感受差距了。下面这张表参考它(第 2 章表 2.2、第 9 章表 9.1),并补充了几项存储工程师天天打交道的操作:
| 操作 | 典型延迟 | 放大后(1 个 CPU 周期 = 1 秒) |
|---|---|---|
| 1 个 CPU 周期(约 3.5 GHz) | 0.3 ns | 1 秒 |
| L1 缓存访问 | ~1 ns | 3 秒 |
| L2 缓存访问 | ~3 ns | 10 秒 |
| L3 缓存访问 | ~10 ns | 33 秒 |
| DRAM 内存访问 | ~100 ns | 6 分钟 |
| CXL 扩展内存访问 | ~200~400 ns | 11~22 分钟 |
| RDMA 网络往返(同机房) | ~2~5 μs | 2~5 小时 |
| NVMe SSD 4 KiB 随机读 | ~50~100 μs | 2~4 天 |
| 同机房 TCP 往返 | ~50~200 μs | 2~8 天 |
| SATA SSD 4 KiB 随机读 | ~100~200 μs | 4~8 天 |
| 分布式块存储 4 KiB 写(三副本,全闪) | ~0.5~2 ms | 19 天~2 个半月 |
| 机械盘顺序读(无寻道) | ~1 ms | 1 个多月 |
| 7200 转机械盘随机读 | ~8 ms | 10 个月 |
| 局域网自建对象存储小对象 GET | ~1~10 ms | 1~12 个月 |
| 公有云对象存储首字节 | ~几十~200 ms | 2~20 年 |
| 跨洲网络往返 | ~100~180 ms | 11~19 年 |
| SCSI 命令超时 | 30 s | 3 千年 |
| 磁带库装载 + 定位 | 数十秒~数分钟 | 数千~数万年 |
从这张表里读出三件事
**第一,每往下一层,大约慢 10~1000 倍。**内存比 L3 慢 10 倍,NVMe 比内存慢 500~1000 倍,机械盘又比 NVMe 慢 100 倍。所以"多一次落盘"和"多一次内存访问"根本不是一个量级的开销,缓存命中率从 99% 掉到 95%,性能可能直接腰斩。
**第二,越往下,介质本身的延迟占比越小,软件和网络的占比越大。**NVMe 闪存读一次几十微秒,但一次分布式块存储写要 1 ms 左右——多出来的时间花在网络往返、多副本等待、软件栈和日志上。这也是为什么阶段 5 会专门讲 RDMA:当介质快到微秒级时,TCP 协议栈本身就成了瓶颈。
**第三,要能一眼认出"不对劲"的数字。**记住几个锚点:
- NVMe 的
await长期在 1 ms 以上 → 要么队列打满了,要么盘有问题; - 机械盘的随机读
await在 5~15 ms → 正常,别急着调; - 全闪分布式存储的 4K 写延迟到了 10 ms → 一定有东西在排队。
带宽:另一把尺子
延迟回答"一次要多久",带宽回答"一秒能搬多少"。下面是常见链路和设备的理论或典型顺序带宽(截至写作时的主流规格):
| 链路 / 设备 | 带宽(约) | 备注 |
|---|---|---|
| 机械盘顺序读写 | 200~280 MB/s | 外圈快、内圈慢 |
| SATA 3(6 Gb/s) | ~550 MB/s | SATA SSD 被接口卡住的上限 |
| SAS 3 / SAS 4(12 / 24 Gb/s) | ~1.1 / ~2.2 GB/s | 单端口 |
| NVMe PCIe 4.0 x4 | ~7 GB/s | |
| NVMe PCIe 5.0 x4 | ~14 GB/s | |
| 25 / 100 GbE | ~3 / ~12 GB/s | 扣除协议开销后更低 |
| 400 Gb/s InfiniBand NDR | ~50 GB/s | AI 集群常见 |
| 单通道 DDR5 内存 | ~40~50 GB/s | 多通道叠加 |
一个常用的心算:一块 PCIe 4.0 NVMe 的顺序带宽,差不多能塞满一张 50 GbE 网卡。所以一台插了 12 块 NVMe 的存储服务器,瓶颈几乎一定在网络,不在盘。这个结论在阶段 5 容量与性能规划里会反复用到。
数据住在哪里:五种接入方式
知道了"多快",再看"在哪"。按存储离应用的远近和访问接口,常见的有五种形态。先看一张总图,重点看文件系统在哪一侧:
DAS SAN NAS Object
+-----------+ +-----------+ +-----------+ +-----------+
| App | | App | | App | | App/SDK |
| FS | | FS | | NFS/SMB | | S3 (HTTP)|
| Block | | Block | | client | | client |
+-----+-----+ +-----+-----+ +-----+-----+ +-----+-----+
| SATA/SAS | FC / iSCSI | NFS / SMB | HTTP
| NVMe | NVMe-oF | over TCP | over TCP
+-----+-----+ +-----+-----+ +-----+-----+ +-----+-----+
| Disks | | Array | | NAS head | | Gateway |
+-----------+ | (LUN) | | FS | | meta+data |
| Disks | | Disks | | Disks |
+-----------+ +-----------+ +-----------+
FS on host FS on host FS on storage no FS, bucket/key
Distributed / SDS:很多台 DAS 服务器 + 软件,对外提供块、文件或对象接口
+--------------------------------------------------------------------+
| client (RBD / CephFS / S3 / private protocol) |
+------------------------------+-------------------------------------+
| Ethernet / RDMA
+-------------+ +-------------+ +-------------+ +-------------+
| node 1 | | node 2 | | node 3 | | node N |
| disk disk.. | | disk disk.. | | disk disk.. | | disk disk.. |
+-------------+ +-------------+ +-------------+ +-------------+DAS:直连存储
直连存储(Direct-Attached Storage,DAS)就是盘直接接在服务器上:主板上的 SATA 口、HBA 卡后面的 SAS 盘、PCIe 插槽里的 NVMe。你的笔记本、大多数数据库服务器、Ceph 和 GPFS 的每个存储节点,本质上都是 DAS。
- 优点:最快、最简单、最容易观测——每块盘操作系统都看得见,
iostat能一块块看。 - 缺点:数据被锁在这台机器里。机器挂了,数据就不可访问;容量也受机箱槽位限制。
盘和主板之间通常还隔着一层控制器:HBA(直通)卡把盘原样交给操作系统(也叫 JBOD 模式),RAID 卡则把多块盘合成一个虚拟盘,往往还带有电池保护的写缓存。Gregg 在第 9 章提到一个趋势:CPU 算力过剩之后,越来越多的方案回到软件 RAID 和"直通 + 上层软件冗余",因为观测性更好、坏了也更好修。Ceph 官方的硬件建议也倾向于让 OSD 盘走 HBA / JBOD 直通,把冗余交给 Ceph 自己,而不是再套一层 RAID 卡。
SAN:存储区域网络
存储区域网络(Storage Area Network,SAN)把"块设备"搬到了网络另一端:存储阵列把一块逻辑卷(LUN)通过光纤通道(Fibre Channel,FC)、iSCSI 或 NVMe-oF 导出,服务器上看到的就是一块普通的盘(/dev/sdX、/dev/nvmeXnY),自己在上面建文件系统。
- 优点:集中管理、高可用(阵列双控、多路径),服务器挂了可以把 LUN 挂到另一台上继续跑。传统数据库、虚拟化平台的主力。
- 缺点:贵;共享的是"块",不是"文件"。
云上的"云硬盘"(如 AWS EBS)在使用方式上也是块存储,只是背后换成了云厂商的分布式系统。
NAS:网络附加存储
网络附加存储(Network-Attached Storage,NAS)更进一步,把文件系统本身也放到了服务器那一侧,客户端通过 NFS(Linux 世界)或 SMB(Windows 世界)访问的是"文件和目录"。
- 优点:天然多客户端共享,权限、配额、快照都在服务端统一管理,客户端零配置。
- 缺点:所有元数据操作(
open、stat、ls)都要走网络,小文件多的场景很痛;单台 NAS 头的性能有上限。
SAN 和 NAS 的本质区别就一句话:文件系统在客户端,还是在存储端。后面在块、文件、对象:三种存储语义和网络存储里会亲手搭 iSCSI 和 NFS,体会这个区别。
对象存储
对象存储(Object Storage)干脆放弃了目录树和 POSIX 语义,只提供一个扁平的"桶(Bucket)+ 键(Key)→ 对象(Object)"的映射,通过 HTTP 接口访问。事实标准是 Amazon S3 的 API:PUT 一个对象、GET 一个对象、LIST 一个前缀。
- 优点:几乎无限水平扩展;HTTP 接口让任何语言、任何地方都能访问;对象整体写入、不支持原地修改,这个限制反而让一致性和多副本变得简单,成本可以做到很低。
- 缺点:不能像文件一样改其中几个字节;
rename一个"目录"要逐个复制对象;单次请求延迟高。
备份、归档、图片视频、数据湖、AI 训练数据集和 checkpoint,都在往对象存储上走。阶段 3 的对象存储与 S3 协议会深入。
分布式存储
前面四种是按"接口"分的,分布式存储(Distributed Storage)则是按"架构"分:用很多台普通 x86 服务器的本地盘(DAS),通过软件组成一个大存储池,数据自动分布、多副本或纠删码冗余、节点坏了自动恢复。它对外可以提供块、文件、对象中的一种或几种接口,所以也常被叫作软件定义存储(Software-Defined Storage,SDS)。
| 系统 | 对外接口 | 典型场景 |
|---|---|---|
| Ceph | 块(RBD)、文件(CephFS)、对象(RGW) | 私有云、Kubernetes、通用存储底座 |
| IBM Storage Scale(GPFS) | 并行文件系统 | HPC、AI 训练、大规模共享文件 |
| JuiceFS | POSIX 文件系统(数据放对象存储) | 云原生、AI 数据集 |
| 3FS | 面向 AI 的并行文件系统 | 大模型训练与推理 |
| MinIO / RustFS | 对象存储 | S3 兼容对象存储 |
这是本课程阶段 3 到阶段 5 的主战场。
五种方式放在一起比
| DAS | SAN | NAS | 对象存储 | 分布式存储 | |
|---|---|---|---|---|---|
| 访问单位 | 块 | 块 | 文件 | 对象 | 块 / 文件 / 对象 |
| 文件系统在哪 | 本机 | 本机 | 存储端 | 无(扁平命名空间) | 取决于接口 |
| 典型协议 | SATA、SAS、NVMe | FC、iSCSI、NVMe-oF | NFS、SMB | HTTP(S3) | RBD、CephFS、私有协议 |
| 多机共享 | 否 | 块级(需集群文件系统) | 是 | 是 | 是 |
| 扩展方式 | 加盘 | 加阵列 / 扩柜 | 加 NAS 头 | 加节点 | 加节点 |
| 延迟 | 最低 | 低 | 中 | 高 | 中 |
| 主要风险 | 单机故障 | 阵列 / 网络故障 | 元数据瓶颈 | 语义不匹配 | 运维复杂度 |
存储工程师在做什么
存储工程师(也叫存储运维、存储 SRE)对一件事负最终责任:数据不丢、服务可用、性能够用、成本可控。这四件事按重要性排序,而且第一件没有商量余地——服务挂了可以恢复,数据丢了就是丢了。
一套存储的生命周期
需求分析 → 容量/性能规划 → 选型与采购 → 上架与部署 → 交付(StorageClass / 挂载点 / Bucket)
→ 日常运维(监控、巡检、变更、故障处理、调优)→ 扩容与升级 → 下线与数据迁移 → 下一轮需求分析日常职责
| 职责 | 频率 | 具体在干什么 | 对应课程 |
|---|---|---|---|
| 监控与巡检 | 每天 | 看集群健康、容量水位、慢请求、坏盘预警(SMART) | 存储监控与告警 |
| 故障处理 | 随时 | 换坏盘、处理 OSD / MDS 异常、恢复降级数据 | Ceph 故障排查闯关 |
| 用户支持 | 每天 | "为什么我的训练读数据这么慢?""PVC 为什么一直 Pending?" | 性能分析方法论 |
| 变更 | 每周 | 扩容、升级、参数调整,按 SOP 执行、可回退 | Ceph Day-2 运维 |
| 性能测试 | 每次上线 / 变更前后 | 建立基线、验收新硬件、对比方案 | 基准测试:fio 与 elbencho |
| 容量规划 | 每月 / 每季度 | 根据增长趋势提前采购,算清副本 / EC 下的可用容量 | 容量与性能规划 |
| 数据保护 | 持续 | 快照、备份、跨站点复制,定期演练恢复 | RGW 对象网关 |
| 选型与架构 | 按项目 | 为新业务(比如新的 GPU 集群)设计存储方案 | AI 训练存储选型 |
| 值班与复盘 | 轮值 | 响应告警,故障后写复盘、补监控、改流程 | On-call、SOP 与故障复盘 |
一个普通的工作日
- 09:30 看昨晚的告警:一个 OSD 的 SMART 报告
Reallocated_Sector_Ct在涨,开工单准备换盘。 - 10:30 算法团队反馈训练任务读数据慢。用
iostat和客户端指标一看,存储端很闲,是数据加载线程只开了 2 个。给出建议,顺手把排查过程写进知识库。 - 14:00 执行本周变更:给集群加 2 台节点。按 SOP 先设置回填限速,再加 OSD,盯着数据均衡进度。
- 16:00 容量周报:按近 30 天增速,还有 11 周写到 75% 水位,提交采购申请。
- 17:30 交接给晚班值班同事,说明回填还要跑 6 小时,期间性能会略有下降。
你会发现,真正"动手敲命令"的时间并不多,大部分时间在看数据、做判断、控风险。
需要的知识结构
- 硬件:盘、控制器、PCIe、网卡——知道每种设备的性能上限和坏法(阶段 1)。
- Linux 内核 I/O:页缓存、块层、文件系统——这是一切观测和调优的基础(阶段 0~2)。
- 网络:TCP、RDMA、交换机配置——分布式存储一半的问题是网络问题(阶段 3、5)。
- 分布式系统:数据分布、一致性、故障域、仲裁——理解"为什么集群会这样反应"(阶段 3)。
- 自动化:Shell、Python 或 Go,Ansible,Kubernetes——一个人管几十上百台存储节点,靠的是自动化(阶段 4)。
动手练习
- 在你的电脑(或实验虚拟机)上执行
lscpu --caches和free -h,记下 L1 / L2 / L3 缓存和内存大小,把它们对应到本课的"存储层次"图上。 - 用
ioping -c 10 -C .和ioping -c 10 -D .分别测一次,计算两者延迟相差多少倍,并解释差距来自哪里。 - 列出你所在团队(或你熟悉的某个系统)用到的存储,把每一种归到 DAS / SAN / NAS / 对象存储 / 分布式存储中的一类,并写出它对外的访问协议。
- 按"1 个 CPU 周期 = 1 秒"的比例,自己算一下"一次 30 ms 的慢 I/O"放大后相当于多久。
- 假设一台存储服务器有 12 块 PCIe 4.0 NVMe 和 2 张 100 GbE 网卡,估算它的盘总带宽和网络总带宽,判断瓶颈在哪一侧。
自测
为什么说"持久化分界线"在 DRAM 和 SSD 之间?它对 write() 意味着什么?
DRAM 及以上的寄存器、CPU 缓存都是易失的,断电数据即丢失;SSD、HDD 等非易失介质断电后数据仍在。Linux 默认的 write() 只把数据拷贝到内存中的页缓存就返回成功,此时数据还在分界线以上,掉电会丢失。要保证持久化,需要 fsync()、O_SYNC 等手段让数据真正落到设备上(设备自己的易失缓存也要刷掉)。
一块 NVMe SSD 的 await 长期在 5 ms 左右,正常吗?为什么?
不正常。NVMe 单次 4 KiB 读的典型延迟在几十到一百微秒量级,5 ms 已经接近机械盘的随机读延迟。常见原因是队列深度过高导致排队、盘在做垃圾回收或已接近写满、盘本身有故障,或者上层(如 RAID、设备映射层)引入了额外等待,需要进一步观测定位。
SAN 和 NAS 最本质的区别是什么?
文件系统所在的位置。SAN 导出的是块设备,文件系统建在客户端(服务器)上;NAS 导出的是文件和目录,文件系统在存储端,客户端通过 NFS / SMB 等文件协议访问。
两台服务器同时挂载同一个 iSCSI LUN,各自 mount 同一个 XFS 文件系统,会发生什么?
文件系统很可能被损坏。XFS、ext4 这类本地文件系统假设自己独占设备,会各自缓存和修改元数据,互相覆盖对方的写入。多机共享同一块盘必须使用 GPFS、OCFS2、GFS2 这类有分布式锁的集群文件系统,或者改用 NAS / 分布式文件系统。
为什么越靠近分布式存储,软件和网络在总延迟里的占比越大?
介质越来越快(NVMe 读只要几十微秒),但一次分布式写要经过客户端软件栈、网络往返、主副本转发给其他副本、各副本写日志并回复确认,每一步都是几十到几百微秒。最终总延迟到了毫秒级,介质本身只占很小一部分,所以高性能分布式存储要靠 RDMA、减少副本往返、精简软件路径来降低延迟。
参考资料
- Brendan Gregg,《Systems Performance, 2nd Edition》第 2 章 2.3.2 Time Scales、第 9 章 9.3.2 Time Scales 与 9.4.3 Storage Types
- Brendan Gregg:Systems Performance 2nd Edition 主页
- Latency Numbers Every Programmer Should Know(交互版)
- Ceph 文档:硬件推荐
- AWS 文档:Amazon S3 性能设计模式
- SNIA 词典(存储术语)
- ioping 项目主页