磁盘 IO 与顺序写

数据库与日志系统优先使用顺序写:日志结构存储把随机写转为顺序追加;评估 IO 时看 IOPS、吞吐与延迟三个维度,并按读写比例选择存储介质。

磁盘 IO 该怎么评估

磁盘性能有三个互不等价的维度:IOPS(每秒操作数)、吞吐(每秒字节数)和延迟(单次操作的响应时间)。随机小块访问受 IOPS 与延迟约束,顺序大块访问受带宽约束,因此同一块盘在不同访问模式下的表现可能相差很多。数据库与日志系统普遍采用日志结构存储与预写日志:把随机写转成顺序追加,用批量刷盘摊薄开销,代价是刷盘策略要在性能与掉电一致性之间取舍。

基本信息

指标IOPS、带宽、P99 延迟与队列深度
模式顺序写吞吐高,随机写对介质特性敏感
手段WAL 与日志结构、批量刷盘、合理预读
观测工具iostat 看设备级指标,fio 做定向压测

典型使用场景

  • 数据库选盘:按随机读写比例选择介质与规格
  • 日志系统写入:顺序追加为主,关注带宽与刷盘延迟
  • 批量导入:大批量写入期间临时空间与刷盘压力同时上升
  • 虚拟化与容器共享存储:多个工作负载争用同一存储后端
  • 云盘选型:确认基准性能与突发额度的实际表现

压测与观测要点

压测与观测要点
# 4K 随机写压测(示例)
fio --name=randwrite --ioengine=libaio --rw=randwrite --bs=4k --iodepth=32 --runtime=60

# 观测:iostat -x 1,关注 await、%util 与队列深度
# 随机写看 IOPS 与 P99 延迟;顺序写看带宽
# 云盘注意突发积分与 IOPS 配额上限

iostat 关键列读法

列含义异常信号
r/s、w/s每秒读写次数与预期业务模型差异大,说明访问模式被改变
rkB/s、wkB/s每秒读写字节数带宽接近规格上限时长尾延迟上升
await平均 IO 等待时间(含排队)持续上升说明队列积压或设备饱和
%util设备繁忙时间占比长期接近 100% 表示设备已饱和
aqu-sz平均队列深度深度上升而吞吐不增,说明已到瓶颈

使用要点

  • 随机写场景看 IOPS 与 P99 延迟,顺序写场景看带宽,指标选错会得出错误结论
  • 刷盘策略调优要评估掉电一致性:关闭同步刷盘提升写入性能,同时扩大数据丢失窗口
  • 注意突发额度机制:部分云盘用积分或额度模型,长时间高负载后性能会明显下降
  • 压测要模拟真实访问模式:块大小、读写比例、并发深度与业务不一致时结论不可用
  • 关注共享存储的邻居影响:同一后端被多个工作负载争用时,表现会随他人负载波动
云盘性能有配额上限:突发积分与 IOPS 上限要在压测中确认,避免只按规格估算;持续高负载下实际可用性能可能远低于峰值。
关闭同步刷盘或使用更宽松的刷盘策略会提升写入性能,但掉电时可能丢失最近若干秒的已提交数据;这类取舍要按业务对数据丢失的容忍度决定,并明确记录。

易错点

  • 用吞吐指标评估随机写场景,规格误判,上线后 IOPS 严重不足
  • 刷盘策略调优忽略掉电一致性要求,故障时丢失已确认写入的数据
  • 只看平均 await 不看分位,尾部的慢 IO 在平均值里被掩盖
  • 压测块大小与并发深度不匹配业务访问模式,结论不可复现
  • 忽略共享存储的邻居影响,其他工作负载上线后性能突然下降

数据来源与参考

  • 《数据密集型应用系统设计》(Kleppmann)第 3 章
  • 《性能之巅(第 2 版)》(Gregg):磁盘 IO
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌