记录一下那天晚上的排查过程。阿里云 ESSD 盘上给 /data 的 fstab 加了 discard 选项,之后小文件写入的延迟从 3ms 涨到 12ms,iostat 里写请求的队列还经常排队。
刚开始盯着「云盘的 TRIM 需要透传到后端存储,链路延迟远高于本地 SSD」,折腾了半个多小时,排掉了。
真正麻烦的地方在于,几个原因的现象几乎一样。实时 discard 会在每次删除时同步发出 TRIM,删文件变成一次额外的慢操作。还有一种是TRIM 请求与业务写请求抢同一个队列,顺序被打乱。
不容易想到的是,批量删除场景下 discard 集中触发,瞬时队列深度被打满。
量化删除操作的耗时
time rm -rf /data/tmp/1000files && iostat -x 1 3 /dev/vdb
去掉 discard 改成按周裁剪
sed -i 's/,discard//' /etc/fstab && mount -o remount /data
手动跑一次 fstrim 观察耗时
time fstrim -av
剩下的就是用定时任务在低谷执行
printf '[Unit]\nDescription=weekly fstrim\n[Service]\nType=oneshot\nExecStart=/sbin/fstrim -av\n' > /etc/systemd/system/fstrim-weekly.service
改完先别撤,确认这几项。remount 后 findmnt 的选项里不再有 discard,小文件写入 p99 回到 5ms 以内,fstrim 在凌晨执行完毕且耗时在可接受范围。
云盘上实时 discard 的实际收益很小,因为后端存储自己会回收;定时 fstrim 更好控制窗口,但要注意它在裁剪期间会占一定 IO。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
