默认挂载易致卡死、丢数据等问题,须显式设置hard,intr,timeo=600,retrans=2,proto=tcp,rsize/wsize匹配网络能力,禁用atime,fstab中必加_netdev且避免defaults。

直接挂载 NFS 通常能用,但默认参数在生产环境大概率会出问题:卡死、写入丢失、元数据不一致、小文件慢得离谱——这不是 NFS 本身的问题,而是 mount 时没选对参数。
为什么 mount -t nfs server:/path /mnt 会卡住或超时?
默认是 hard + intr 未启用 + timeo 过短。一旦网络抖动或服务端响应延迟,客户端会无限重试,进程假死(D 状态),Ctrl+C 也无效。
- 必须显式加
hard,intr:保证数据不丢,又允许中断挂起操作 -
timeo=600(单位是 0.1 秒,即 60 秒)比默认的 70(7 秒)更耐网络波动 -
retrans=2控制重试次数,再高只会拖长阻塞时间 - 内网建议加
proto=tcp(NFSv4 默认已用 TCP,但显式声明更稳妥);跨公网必须用tcp,UDP 容易丢包导致重传风暴
rsize 和 wsize 设多少才不翻车?
设太大反而降低性能:超过 MTU 或服务器/网卡处理能力,触发分片、丢包、重传。不是越大越好,要匹配链路实际能力。
- 千兆局域网常见稳定值:
rsize=1048576,wsize=1048576(1 MB) - 万兆或 RDMA 网络可试
4194304(4 MB),但需验证nfsiostat -h中 retrans 值是否突增 - NFSv3 下
rsize/wsize不能超过服务器/proc/sys/sunrpc/tcp_max_xmit_size,否则被截断回退到默认 32KB - 绝对不要设成
0或负数——有些旧内核会静默失败,挂载看似成功,实则用默认 1024
noatime、nodiratime 和 noac 到底该开哪个?
三者都减少元数据更新,但粒度和风险不同。高频读场景必开,但数据库类强一致性应用要谨慎。
-
noatime:禁用文件访问时间更新,安全且收益大,建议无条件加 -
nodiratime:禁用目录 atime,常和noatime一起用,noatime已隐含此行为(Linux 2.6.30+),单独写不报错但冗余 -
noac:完全禁用属性缓存(大小、mtime 等),每次stat()都走网络请求——性能暴跌,仅用于极少数要求秒级元数据一致的场景(如分布式锁文件轮询),日常严禁使用
fstab 自动挂载时最容易漏掉的关键点
/etc/fstab 里写错一个参数,系统可能卡在启动阶段进不了 login prompt,尤其当 NFS 服务端不可达时。
- 必须加
_netdev:告诉 init 系统等网络就绪后再挂载,否则 systemd 会并行尝试,大概率失败 - 避免用
defaults:它包含exec,suid,dev,对共享存储不安全;应显式写rw,hard,intr,timeo=600,retrans=2,rsize=1048576,wsize=1048576,noatime,_netdev - 不要依赖
bg来“后台重试”:fstab 中bg只影响挂载失败后的重试行为,无法解决启动时阻塞,_netdev才是正解 - 测试命令:改完 fstab 后,先运行
sudo mount -a,观察是否报错,别等重启才发现
真正难的不是记住所有参数,而是在 rsize 和 noac 之间做取舍,在 hard 和可用性之间找平衡点——这些没有银弹,只能结合 nfsiostat、tcpdump 和业务读写模式反复验证。


















