麒麟系统NFS共享性能调优:5个关键参数实测与优化指南
1. 从一次文件拷贝说起NFS共享慢到底慢在哪前阵子帮一个做三维渲染的团队排查问题他们的素材库放在一台麒麟系统的服务器上通过NFS共享给十几台工作站调用。症状很典型小文件读写还行一旦碰到几个GB的贴图包或者视频素材拷贝速度就掉到十几MB/s千兆内网跑出了百兆网的手感。更奇怪的是用scp走SSH传同样的文件反而能跑到七八十MB/s。这就说明网络链路本身没问题瓶颈出在NFS这一层。NFS共享速度慢在麒麟系统银河麒麟V10、中标麒麟等上是个高频问题尤其是国产化替代推进之后很多单位从Windows共享或者Samba迁移到NFS默认配置直接拿来用性能自然不理想。这篇文章就围绕NFS、麒麟系统、性能调优、rsize、wsize这几个核心点把我实测过的5个关键参数掰开揉碎讲清楚。每个参数我都会给出实测对比数据、调整方法、以及为什么这么调的原理。适合谁看如果你正在用麒麟系统做NFS服务端或者客户端遇到过拷贝慢、并发卡、大文件传输掉速的问题这篇内容可以直接抄作业。如果你只是刚接触NFS也能通过这篇文章理解NFS性能调优的基本逻辑少走弯路。先说结论NFS性能调优不是玄学核心就是减少网络往返次数、增大单次传输块、合理利用缓存。下面这5个参数基本覆盖了80%的性能问题。2. 调优前的准备工作别急着改参数2.1 先搞清楚你的瓶颈在哪一层很多人一上来就改rsize和wsize改完发现没效果然后就开始怀疑人生。我踩过的坑告诉我调优之前必须先定位瓶颈。NFS的性能链路大概是这样的应用层读写 → 客户端VFS → NFS客户端 → 网络传输 → NFS服务端 → 服务端VFS → 磁盘IO。任何一层出问题表现都是“慢”但解法完全不同。怎么快速定位我一般用三个工具组合nfsstat -c和nfsstat -s看客户端和服务端的RPC统计重点看retrans重传率和timeout。重传率高说明网络或者服务端响应有问题。iostat -x 1看服务端磁盘的%util和await。如果磁盘util常年100%那瓶颈在磁盘调NFS参数没用。sar -n DEV 1看网络带宽是否跑满。千兆网理论125MB/s实际能跑到110MB/s左右。提示如果iostat显示磁盘util已经满了先解决磁盘问题换SSD、做RAID、调整IO调度器NFS参数怎么调都是白搭。2.2 确认NFS版本和挂载方式麒麟系统默认可能用的是NFSv3或者NFSv4两者调优思路有差异。用nfsstat -m或者mount | grep nfs可以看到当前挂载的版本和参数。NFSv4默认支持一些更好的特性比如复合操作、更好的缓存一致性但很多老环境还是v3。我实测下来在麒麟V10上NFSv4.1的性能和稳定性都比v3好一截建议优先用v4。另外要确认挂载时用的是hard还是softintr还是nointr。生产环境我强烈建议用hard挂载虽然偶尔会卡住但不会丢数据。soft挂载在网络抖动时容易返回错误导致应用层拿到脏数据。2.3 记录基线数据改参数之前一定要先测一组基线数据。我通常用dd配合convfdatasync来测顺序写用fio测随机读写。简单点的话直接拷贝一个大文件用time命令记录耗时算平均速度。比如# 测写速度 dd if/dev/zero of/mnt/nfs/testfile bs1M count4096 convfdatasync # 测读速度先清缓存 echo 3 /proc/sys/vm/drop_caches dd if/mnt/nfs/testfile of/dev/null bs1M基线数据是后面所有对比的参照物没有基线你根本不知道调优有没有效果。3. 五个关键参数逐个拆解与实测对比3.1 rsize和wsize最核心的两个参数rsize和wsize是NFS客户端和服务端协商的单次读写块大小单位是字节。这两个参数直接决定了每次RPC请求能传多少数据。默认值在麒麟系统上通常是32KB或者64KB这个值在现代千兆甚至万兆网络下明显偏小。原理很简单NFS是基于RPC的每次读写都要走一次网络往返。如果每次只传32KB传1GB文件需要32768次往返网络延迟再低也扛不住。把rsize和wsize调大比如调到1MB往返次数直接降到1024次性能提升非常明显。但也不是越大越好。我实测过从32KB到1MB的多个档位在千兆网络下512KB到1MB是比较甜的点。再往上比如2MB提升就不明显了反而可能因为分片导致重传成本变高。实测数据千兆网络NFSv4.1服务端SSD客户端SSDrsize/wsize顺序写速度顺序读速度重传率32KB默认28MB/s35MB/s0.5%128KB65MB/s78MB/s0.2%512KB98MB/s108MB/s0.1%1MB105MB/s112MB/s0.1%2MB106MB/s113MB/s0.3%可以看到从32KB调到512KB写速度提升了3.5倍。这就是为什么很多人说“改了rsize/wsize像换了一台机器”。怎么改在客户端挂载时指定mount -t nfs -o rsize1048576,wsize1048576,vers4.1 192.168.1.100:/data /mnt/nfs或者写进/etc/fstab192.168.1.100:/data /mnt/nfs nfs rsize1048576,wsize1048576,vers4.1,hard,intr 0 0注意rsize和wsize的最大值受服务端和客户端共同限制。如果服务端配置了RPCNFSDCOUNT或者/etc/nfs.conf里的限制客户端设再大也没用。另外NFSv3下最大值通常是1MBNFSv4可以更大但实际受网络MTU影响。3.2 async vs sync服务端写入策略的取舍这个参数在服务端的/etc/exports里配置。sync表示服务端收到写请求后必须落盘才返回成功async表示先写到内存缓存就返回后续再刷盘。默认情况下很多麒麟系统的NFS服务端用的是sync这是为了数据安全。但sync模式下每次写都要等磁盘确认延迟高吞吐低。async模式下写性能可以提升几倍但风险是服务端断电可能丢数据。我实测过同一台服务端sync和async的写速度差距模式顺序写速度数据安全性sync45MB/s高落盘才返回async110MB/s中断电可能丢最近数据怎么选如果是临时数据、渲染缓存、日志类场景async完全可以接受。如果是数据库备份、重要文档老老实实sync。折中方案是用sync但配合服务端SSD和写缓存或者用NFSv4的pNFS特性做并行写。配置方法# /etc/exports /data 192.168.1.0/24(rw,async,no_root_squash)改完执行exportfs -ra生效。提示async不是万能药。如果服务端内存小大量写请求会把内存打满反而导致卡顿。建议服务端内存至少16GB起步并且监控/proc/meminfo里的Dirty值。3.3 nconnect多连接并行传输nconnect是NFSv4.1引入的一个特性允许客户端和服务端之间建立多个TCP连接并行传输数据。默认是1可以调到8甚至16。这个参数对高延迟网络或者多核客户端效果特别明显。原理是单个TCP连接受限于拥塞窗口和接收窗口很难跑满高带宽。多个连接可以绕过这个限制把带宽吃满。我在一个跨机房的场景里实测RTT大概2ms单连接只能跑到300MB/s万兆网调到nconnect8之后直接跑到900MB/s。麒麟系统内核版本如果比较新4.18以上基本都支持nconnect。挂载时加上mount -t nfs -o nconnect8,rsize1048576,wsize1048576,vers4.1 192.168.1.100:/data /mnt/nfs实测对比万兆网络RTT 2msnconnect顺序读速度CPU占用1320MB/s15%4680MB/s35%8920MB/s55%16940MB/s70%可以看到8连接之后收益递减CPU占用却上去了。所以nconnect8是个比较平衡的值。注意nconnect需要服务端也支持并且服务端的nfsd线程数要够。如果服务端RPCNFSDCOUNT太小多连接反而会排队。建议服务端nfsd线程数调到64以上。3.4 noatime别让访问时间拖后腿atime是文件访问时间。每次读文件文件系统都要更新atime这意味着一次读操作变成了“读写”。在NFS场景下这个写操作还要走网络到服务端开销翻倍。noatime挂载选项告诉文件系统不要更新atime读操作就是纯读。这个参数对读密集型场景提升明显尤其是大量小文件读取。实测对比读取10000个小文件挂载选项耗时提升默认atime48秒基准noatime32秒33%配置方法mount -t nfs -o noatime,rsize1048576,wsize1048576 192.168.1.100:/data /mnt/nfs提示noatime的唯一副作用是ls -lu看到的时间不准。对于绝大多数应用来说这个时间根本没人看。放心用。3.5 服务端nfsd线程数别让服务端成为瓶颈前面几个参数都是客户端或者传输层的但服务端如果线程数不够客户端再优化也白搭。nfsd线程数决定了服务端能同时处理多少个NFS请求。默认值在麒麟系统上通常是8对于多客户端并发场景明显不够。查看当前线程数cat /proc/fs/nfsd/threads调整方法临时echo 64 /proc/fs/nfsd/threads永久生效需要改/etc/nfs.conf或者/etc/sysconfig/nfs# /etc/nfs.conf [nfsd] threads64然后重启nfs-server服务。实测对比10个客户端并发写nfsd线程数总吞吐平均延迟8180MB/s45ms32420MB/s18ms64580MB/s12ms128590MB/s12ms线程数不是越多越好太多会导致上下文切换开销。一般建议设置为CPU核心数的2到4倍。比如16核的服务器设64比较合适。4. 完整调优实操从零到跑满千兆4.1 服务端配置假设服务端是麒麟V10IP是192.168.1.100共享目录是/data。步骤如下第一步安装NFS服务端yum install nfs-utils -y systemctl enable nfs-server systemctl start nfs-server第二步配置/etc/exports/data 192.168.1.0/24(rw,async,no_root_squash,no_subtree_check)这里async提升写性能no_root_squash方便管理生产环境慎用no_subtree_check减少检查开销。第三步调整nfsd线程数# /etc/nfs.conf [nfsd] threads64第四步生效配置exportfs -ra systemctl restart nfs-server第五步确认防火墙放行NFS相关端口2049、111等。麒麟系统默认可能开了firewalld需要放行firewall-cmd --permanent --add-servicenfs firewall-cmd --permanent --add-servicemountd firewall-cmd --permanent --add-servicerpc-bind firewall-cmd --reload4.2 客户端挂载客户端同样先装nfs-utils然后挂载mount -t nfs -o vers4.1,rsize1048576,wsize1048576,nconnect8,noatime,hard,intr 192.168.1.100:/data /mnt/nfs写进/etc/fstab实现开机自动挂载192.168.1.100:/data /mnt/nfs nfs vers4.1,rsize1048576,wsize1048576,nconnect8,noatime,hard,intr 0 04.3 验证调优效果调优前后各跑一次dd和fio对比数据。我这边实测的结果是调优前顺序写28MB/s调优后105MB/s基本跑满千兆网。小文件读取从48秒降到32秒。10客户端并发从180MB/s提升到580MB/s。提示调优后如果速度没变化先检查mount输出确认参数生效了再看nfsstat有没有重传。有时候是交换机或者网卡的问题比如网卡协商成了百兆或者交换机端口有错误包。5. 常见问题与排查技巧实录5.1 挂载后目录没有权限这是热词里高频出现的问题。NFS挂载后ls提示Permission denied通常有几个原因服务端/etc/exports里的客户端IP段写错了或者用了主机名但DNS解析不了。服务端目录权限不对比如/data是root:root 700客户端普通用户访问不了。root_squash导致客户端root被映射成nobody写不了文件。排查顺序先在服务端showmount -e确认导出列表再在客户端mount确认挂载参数最后检查目录权限。临时解决可以chmod 777但生产环境建议用no_root_squash配合合理的用户映射。5.2 拷贝大文件时卡死NFS卡死通常和hard挂载、网络抖动、服务端磁盘IO有关。如果用了hard挂载网络断了客户端会一直重试表现就是df -h卡住、ls卡住。这时候别急着重启先看nfsstat -c的retrans和timeout。如果服务端恢复了客户端会自动恢复。如果频繁卡死考虑加timeo和retrans参数mount -t nfs -o timeo600,retrans2,hard,intr ...timeo600表示600个十分之一秒也就是60秒超时。retrans2表示重传2次后报错。5.3 速度忽快忽慢这种通常是网络或者服务端负载波动。用sar -n DEV 1看网络有没有丢包用iostat -x 1看服务端磁盘有没有瓶颈。另外检查是不是有多个客户端在抢带宽NFS本身没有QoS先到先得。5.4 麒麟系统特有的坑麒麟系统有些版本默认开了SELinux会拦截NFS访问。如果排查半天权限没问题但还是访问不了试试临时关闭SELinuxsetenforce 0如果有效再针对性配置SELinux策略而不是一关了之。另外麒麟系统的nfs-utils版本可能比较老不支持nconnect。用nfsstat -m看挂载参数里有没有nconnect没有的话需要升级内核或者nfs-utils。常见问题速查表问题可能原因解决方法目录无权限exports配置错误、目录权限、root_squash检查showmount、chmod、no_root_squash大文件卡死网络抖动、hard挂载、服务端IO瓶颈加timeo/retrans、检查iostat速度忽快忽慢网络丢包、多客户端竞争sar看丢包、限制并发nconnect不生效内核或nfs-utils版本低升级内核、确认nfsstat -mSELinux拦截麒麟默认策略setenforce 0测试、配置策略6. 几个容易被忽略的细节调优参数之外还有一些细节会影响NFS性能。比如MTU如果网络支持Jumbo Frame9000把服务端和客户端网卡MTU都调到9000能减少分片提升大块传输效率。我实测在万兆环境下MTU 9000比1500提升大概15%。再比如服务端磁盘的IO调度器。麒麟系统默认可能是cfq或者mq-deadline对于SSD改成none或者noop能降低延迟。改法echo none /sys/block/sda/queue/scheduler还有read_ahead_kb适当调大预读能提升顺序读性能echo 4096 /sys/block/sda/queue/read_ahead_kb这些细节单独看提升不大但叠加起来效果可观。我个人在实际操作中的体会是NFS调优最忌讳“一把梭”。每次只改一个参数测完再改下一个才能知道哪个参数真正起了作用。另外不同硬件、不同网络、不同负载下最优参数可能不一样别人的“最佳实践”只能作为起点最终还是要靠自己的实测数据说话。最后分享一个小技巧如果条件允许服务端和客户端都用SSDNFS性能瓶颈会从磁盘转移到网络这时候调rsize、wsize、nconnect的收益最大。