存储笔记:冷热分层:把热点留在 NVMe,把冷数据放远端

少于 1 分钟阅读

发布于:

本文是「存储笔记:冷热分层:把热点留在 NVMe,把冷数据放远端」的工程化笔记,记录语义/模型定义、可观测信号与排障要点。

存储笔记:冷热分层:把热点留在 NVMe,把冷数据放远端

1. 先把“NVMe 为什么快”说清楚:并行 + 低开销

把 NVMe 的优势概括成核心要点:

把“提交 IO → 完成 IO”做成多队列(SQ/CQ)并行模型,并尽量降低每次 IO 的协议/中断开销。

工程上你通常能直接观察到:

  • 更高 IOPS(尤其是 4KB 随机)
  • 更低平均延迟
  • 更容易把瓶颈暴露到软件栈/CPU/锁(NVMe 够快后,IO 不再“背锅”)

2. 冷热分层到底在优化什么:P99,而不是峰值吞吐

很多系统的体验由 P99/P999 决定,而不是平均值或峰值带宽。

一个很实用的分类:

  • 延迟敏感路径:点查、热点索引、元数据、commit/WAL、请求链路上的关键 KV。
  • 带宽敏感路径:批量 scan、离线任务、异步重建、后台 compaction/GC、跨域复制。

冷热分层的目标是把“必须稳”的路径留在 NVMe,把“可以慢/可被节流”的路径放到更便宜介质,并通过预算把后台任务的抢占限制住。

3. 为什么线上 NVMe 也会抖:最常见不是“盘慢”,而是“排队 + 抢占”

3.1 队列深度(QD)是双刃剑:吞吐↑ 但排队等待↑

QD 变大往往能提升吞吐,但也会把排队等待叠加到尾延迟里:

  • QD 低:更像“低延迟模式”
  • QD 高:更像“高吞吐模式”,但 P99 更容易被放大

实践里经常出现:压测“峰值吞吐”很漂亮,但线上“请求体验”变差,因为线上更在乎尾延迟。

3.2 后台任务抢占:把 NVMe 打成“共享资源”

典型的后台抢占源:

  • RocksDB/LSM:flush/compaction
  • 存储引擎:GC、重建、checksum/压缩
  • 系统层:page cache 回写、文件系统 journal、rebuild/replication

这些任务会把 IO 变成“队列化资源”,进而放大 P99。

3.3 CPU 反而成瓶颈:NVMe 够快后更常见

NVMe 变快后,会更容易遇到:

  • 压缩/校验把 CPU 打满
  • 锁竞争、内存分配、系统调用成为主导
  • 单核热点(绑核/中断/软中断)导致“平均不高但 P99 变差”

4. 怎么观测:别只看 IOPS/带宽,先看“排队与分位数”

建议至少关注:

  • 延迟分位数:P50/P95/P99/P999(平均值最不可信)
  • 队列与在途:QD/in-flight 是否长期偏高(排队信号)
  • IO 延迟分解:提交→设备→完成(如果平台能提供更细拆分更好)
  • 后台欠账:compaction/GC/rebuild backlog 是否持续上升
  • per-core CPU:关键核是否被打爆(不要看平均)

5. 怎么压测:三步把“瓶颈归因”做出来

  1. 设备基线:裸盘 fio(4KB randread/randwrite),固定 QD 与并发,得到延迟/吞吐基线。
  2. 文件系统/缓存层:同样 workload,观察是否被 flush/page cache 影响(延迟长尾/周期性掉速)。
  3. 业务全链路:打开真实的压缩/校验/后台任务,记录 P99 与 backlog 的因果关系。

一个非常实用的做法:画两条曲线

  • 固定并发,逐步增大 QD
  • 固定 QD,逐步增大并发

会很直观地看到“吞吐提升”和“尾延迟恶化”的拐点。

6. 排障顺序(线上 P99 变差)

  1. 先看排队:QD/in-flight 是否异常?是否存在周期性掉速?
  2. 再看后台欠账:compaction/GC/rebuild 是否在追债?是否抢占 NVMe?
  3. 最后看 CPU/锁:NVMe 足够快后,是否已经软件栈主导?

7. 小结

NVMe 带来的价值不只是“更快”,而是“把系统从 IO-bound 推向更可控的瓶颈”。要让线上体验变稳,关键是:用冷热分层把路径拆开 + 用预算约束后台抢占 + 用 QD/并发的拐点控制尾延迟