F2FS 导致 HC620 叠瓦盘卡死?Linux SMR 硬盘排障指南

分析 HC620 这类 Host-managed SMR 叠瓦盘在 F2FS 文件系统下出现 I/O wait 高、系统卡死的原因,并给出挂载参数、调度器和文件系统迁移建议。

HC620 这类氦气封装叠瓦盘配合 F2FS 使用时,如果出现系统卡住、应用无响应、iowait 长时间飙高,通常不是单一参数没调好,而是设备特性和文件系统策略撞在了一起。

Western Digital Ultrastar DC HC620 属于 Host-managed SMR。它更适合顺序写、分区化写入和明确知道底层约束的软件栈。F2FS 则是为闪存设计的日志结构文件系统,虽然能把很多随机写组织成顺序写,但在空间紧张、垃圾回收频繁或元数据更新密集时,仍然可能把机械叠瓦盘拖进很长的内部整理周期。

先确认是不是这类问题

建议先看三个现象:

1
2
3
iostat -x 1
iotop -oPa
dmesg -T | grep -Ei "f2fs|blk|zoned|reset|timeout|I/O error"

如果能看到磁盘 %util 长时间接近 100%,await 很高,系统里大量进程卡在 D 状态,基本可以判断瓶颈在块设备 I/O。

再确认硬盘是否以 zoned 设备暴露:

1
2
lsblk -o NAME,MODEL,SIZE,ROTA,ZONED,SCHED,MOUNTPOINTS
cat /sys/block/sdX/queue/zoned

如果是 Host-managed SMR,普通文件系统和普通随机写负载都可能表现很差。它不像常见的桌面 SMR 盘那样完全由硬盘固件隐藏复杂度,而是更依赖主机端软件理解写入规则。

为什么 F2FS 容易把卡顿放大

SMR 的问题在于写入不是任意覆盖那么简单。叠瓦磁道为了提高容量,会让相邻磁道部分重叠;当写入模式偏随机、覆盖频繁或缓存耗尽时,硬盘需要做额外的数据搬运和整理。

F2FS 的问题在于它本来面向 NAND 闪存。它采用日志结构写入,并通过 segment cleaning 和 garbage collection 回收空间。这个设计在 SSD 上通常很自然,因为 SSD 没有机械寻道;但在机械硬盘上,尤其是 SMR 盘上,GC 产生的读写搬运可能变成明显的长尾延迟。

当 F2FS 后台 GC、前台写入、checkpoint、元数据更新和硬盘自身的 SMR 整理叠在一起时,I/O 队列会被持续占满。表现到用户层,就是复制文件、删除目录、跑下载、解压缩或数据库写入时系统像“冻住”一样。

挂载参数先这样保守调整

如果暂时不能迁移文件系统,可以先从 /etc/fstab 的挂载参数下手:

1
UUID=xxxx  /data  f2fs  defaults,nodiscard,active_logs=2,gc_merge,flush_merge,lazytime  0  0

几个参数的含义:

  • nodiscard:关闭实时 discard。机械硬盘通常不需要像 SSD 那样频繁发送 TRIM/discard,保守关闭更稳。
  • active_logs=2:F2FS 支持 2、4、6 个 active logs,默认通常是 6。降到 2 可以减少日志并发带来的寻道压力。
  • gc_merge:让后台 GC 线程处理部分前台 GC 请求,降低前台进程直接触发慢 GC 时的卡顿。
  • flush_merge:合并 cache flush 请求,底层设备处理 flush 很慢时可能有帮助。
  • lazytime:减少部分访问时间更新带来的元数据写入。

checkpoint=disable 不建议作为常规方案。它确实可能减少 checkpoint 压力,但异常断电或崩溃后的风险更高,而且内核文档也提醒,禁用 checkpoint 后文件系统仍需要 GC 来确保可用空间。除非你非常清楚代价,否则不要把它当成“性能开关”长期使用。

调整 I/O 调度器

机械盘和 SMR 盘通常更需要请求合并与延迟控制。可以先查看当前调度器:

1
cat /sys/block/sdX/queue/scheduler

可尝试切换到 mq-deadline

1
echo mq-deadline | sudo tee /sys/block/sdX/queue/scheduler

如果系统用于桌面交互,也可以测试 bfq。不要只看顺序吞吐,重点观察卡顿是否减少、await 是否下降、交互是否更稳定。

限制 F2FS 后台 GC

F2FS 的 sysfs 路径以实际设备名为准,先确认:

1
ls /sys/fs/f2fs/

然后针对对应挂载设备调整 GC 间隔,例如:

1
2
echo 60000 | sudo tee /sys/fs/f2fs/sdX/gc_min_sleep_time
echo 120000 | sudo tee /sys/fs/f2fs/sdX/gc_max_sleep_time

这里的 sdX 只是示例,实际可能是 sda1dm-0 或其他名称。调大 GC sleep time 的作用是降低后台 GC 抢占 I/O 的频率,但代价是空间回收更慢。磁盘空间越接近满盘,越容易再次触发前台 GC,所以还要留出足够空闲空间。

更推荐的长期方案

如果这块盘存重要数据,最稳妥的方案是备份后换文件系统,或者换更适合的盘。

对大容量机械硬盘,优先考虑:

  • XFS:适合大文件、备份盘、媒体库、归档和顺序写负载。
  • EXT4:兼容性强,行为稳定,排障资料多。

如果是 Host-managed SMR,还要确认你的内核、控制器、文件系统和应用是否真正支持 zoned block device 的使用方式。否则,把它当成普通随机写硬盘用,很容易遇到不可预测的长时间卡顿。

实用建议

这类盘更适合冷数据、归档、备份、媒体文件和顺序写入,不适合下载缓存、容器镜像、虚拟机磁盘、数据库、频繁解压缩目录或小文件随机写。

如果必须继续用 F2FS,建议至少做到:

  • 关闭实时 discard。
  • active_logs=2,减少并发日志。
  • 开启 gc_mergeflush_merge
  • 保持较高空闲空间,不要接近满盘。
  • 避免把下载目录、数据库、虚拟机镜像放在这块盘上。
  • 定期观察 iostat -x 1,不要只看平均速度。

总结一下:HC620 + F2FS 卡死,本质上是 SMR 写入约束、F2FS GC 和机械盘长尾延迟叠加后的结果。临时方案是调挂载参数、调调度器、限制后台 GC;长期方案是迁移到 BTRFS/XFS,或者把这类 SMR 盘放回更适合它的顺序写归档场景。

参考链接:

记录并分享
使用 Hugo 构建
主题 StackJimmy 设计