nfs文件服务器性能调优
2010-12-07 16:04:46 阿炯

NFS 性能分析
NFS 收集各类 NFS 操作执行情况的统计信息,会同出错信息和性能指标。您可以使用以下命令来识别网络问题和观察在您的系统上进行的各类 NFS 操作。

nfsstat 命令
nfsstat 命令显示有关 NFS 和 RPC 接口到客户机和服务器内核的统计信息。这个命令还可以用来重新初始化这些统计信息的计数器(nfsstat -z)。考虑到性能上的问题,RPC 统计信息(-r 选项)是首先需要察看的。NFS 统计信息向您展示了应用程序使用 NFS 的情况。

RPC 统计信息
nfsstat 命令显示了有关 RPC 调用的统计信息,例如:
* 已接收或已拒绝的 RPC 调用的总数
* 从服务器发出的或被服务器拒绝的 RPC 调用的总数
* 试图接收而无法收到 RPC 包的次数
* 长度过短或存在残缺头信息的包数
* 某个调用不得不被重新发送的次数
* 应答与调用不匹配的次数
* 某个调用超时的次数
* 某个调用在客户机句柄繁忙时等待的次数
* 认证信息不得不被刷新的次数

nfsstat 命令输出的 NFS 统计信息部分被分为 NFS V2 和 NFS V3 两部分。而 RPC 统计信息部分被分为面向连接(TCP)和无连接(UDP)两部分。

NFS 服务器信息
对于已接收的 NFS 调用(calls)和由于认证未通过而被拒绝的调用(badcalls)NFS 服务器显示它们的数目,同时也能显示其他很多种类已发生调用的数目和百分比。

下例展示了 nfsstat 命令带 -s 参数选项时输出的服务器部分,如下:
# nfsstat -s
Server rpc:
Connection oriented:
calls   badcalls  nullrecv badlen   xdrcall dupchecks dupreqs
15835      0          0          0          0          772        0
Connectionless:
calls    badcalls  nullrecv badlen   xdrcall dupchecks dupreqs
0          0          0          0          0          0          0

Server nfs:
calls      badcalls   public_v2  public_v3
15835      0          0          0
Version 2: (0 calls)
null       getattr    setattr    root       lookup     readlink   read
0 0%       0 0%       0 0%       0 0%       0 0%       0 0%       0 0%
wrcache    write      create     remove     rename     link       symlink
0 0%       0 0%       0 0%       0 0%       0 0%       0 0%       0 0%
mkdir      rmdir      readdir    statfs
0 0%       0 0%       0 0%       0 0%
Version 3: (15835 calls)
null       getattr    setattr    lookup     access     readlink   read
7 0%       3033 19%   55 0%      1008 6%    1542 9%    20 0%      9000 56%
write      create     mkdir      symlink    mknod      remove     rmdir
175 1%     185 1%     0 0%       0 0%       0 0%       120 0%     0 0%
rename     link       readdir    readdir+   fsstat     fsinfo     pathconf
87 0%      0 0%       1 0%       150 0%     348 2%     7 0%       0 0%
commit
97 0%

RPC 输出的服务器部分(-s)包括下列各项:
calls
从客户机接收到的 RPC 调用总数
badcalls
被 RPC 层拒绝的调用总数
nullrecv
被认为应该接收到而事实上没有捕获可用 RPC 调用的次数
badlen
包截断或包损坏(长度小于最小 RPC 调用标准长度的 RPC 调用数)
xdrcall
报头无法由扩展数据表示(XDR)解码的 RPC 调用数
dupchecks
重复请求高速缓存中已查找过的 RPC 调用数
dupreqs
已发现的重复 RPC 调用数

输出结果中还同时显示了各类调用的数目和各自的百分比。

重复性检查是为那些不能在两次执行中返回同一结果的操作而提供的。这方面经典的例子是 rm 命令。第一个 rm 命令也许成功了,但是如果应答丢失了,客户机将会重发这个命令。我们希望这样的重复请求能获得成功,此时重复高速缓存被查询,如果发现是一个重复请求则相同的(成功的)结果被作为第二个重复请求的结果返回,就好像是由第一个请求所产生的结果一样。

通过查看不同类型操作调用的百分比(如 getattr()、read()、write()、readdir()),您可以决定要用哪一类的调优。例如:如果 getattr() 调用的百分比非常高的话,则调优属性高速缓存是可能会有效果的;如果 write() 调用的百分比过高的话,则磁盘和 LVM 调优就显得重要了;又如果 read() 调用百分比过高,则使用更多的内存用以缓冲文件就能提高性能。

NFS 客户机信息
NFS 客户机显示了已发送和被拒绝的调用数,同时显示已接收客户机句柄的次数(clgets)和各类调用的数目以及各自的百分比。

下例展示了 nfsstat 命令带 -c 参数选项时输出的客户机本分,如下:
# nfsstat -c
Client rpc:
Connection oriented
calls    badcalls  badxids timeouts newcreds badverfs timers
0          0          0          0          0          0          0
nomem    cantconn interrupts
0          0          0
Connectionless
calls    badcalls retrans  badxids  timeouts newcreds badverfs
6553       0          0          0          0          0          0
timers   nomem     cantsend
0          0          0

Client nfs:
calls      badcalls   clgets     cltoomany
6541       0          0          0
Version 2: (6541 calls)
null       getattr    setattr    root       lookup     readlink   read
0 0%       590 9%     414 6%     0 0%       2308 35%   0 0%       0 0%
wrcache    write      create     remove     rename     link       symlink
0 0%       2482 37%   276 4%     277 4%     147 2%     0 0%       0 0%
mkdir      rmdir      readdir    statfs
6 0%       6 0%       30 0%      5 0%
Version 3: (0 calls)
null       getattr    setattr    lookup     access     readlink   read
0 0%       0 0%       0 0%       0 0%       0 0%       0 0%       0 0%
write      create     mkdir      symlink    mknod      remove     rmdir
0 0%       0 0%       0 0%       0 0%       0 0%       0 0%       0 0%
rename     link       readdir    readdir+   fsstat     fsinfo     pathconf
0 0%       0 0%       0 0%       0 0%       0 0%       0 0%       0 0%
commit
0 0%

RPC 输出的客户机部分(-c)包括下列各项:
calls
从客户机向 NFS 发出的调用总数。
badcalls
被 RPC 层拒绝的调用总数。
retrans
由于等待服务器响应而超时重发调用的次数。这仅适用于无连接传输中的 RPC 调用。
badxid
从服务器接收到响应但是没有任何一个未完成调用与之匹配的次数。这意味着服务器可能用了过多的时间来应答。
timeouts
由于等待服务器响应而使调用超时的次数。
newcreds
认证信息不得不被刷新的次数。
badverfs
由于响应中不正确的校验(verifier)而导致调用失败的次数。
timers
调用的超时时长大于或等于指定的最小调用超时值的次数。
nomem
由于内存分配失败而导致调用失败的次数。
cantconn
由于无法连接到服务器而导致调用失败的次数。
interrupts
调用在完成前被某个信号中断的次数。
cantsend
由于无法连接到客户机而导致发送失败的次数。

输出结果中还同时显示了各类调用的数目和各自的百分比。

考虑到性能监视上的问题,nfsstat -c 命令提供信息用以显示网络上是否存在丢弃 UDP 数据包的现象。如果一个网络无法处理某个包,则可能会丢弃它。数据包被丢弃可由以下因素引起:网络硬件的响应时间、网络软件的响应时间或服务器上超负载的 CPU。被丢弃的包并没有真正的丢失,因为一个替代请求会为其发送。

RPC 统计信息中的 retrans 列显示了由于等待响应而超时重发的请求数。这种情形就与丢弃 UDP 包有关。如果 retrans 这一项中的数目持续地超过第一列中调用总数的百分之五时,就表明存在问题,服务器已经不再能满足需求了。可在服务器上使用 vmstat、netpmon和 iostat 命令检查负载。

很大的 badxid 数目意味着请求被发到不同的 NFS 服务器上,但是服务器由于负载过重而没有能够在客户机的 RPC 调用超时重发之前给予响应。每当已发送的请求接收到一个重复的响应时 badxid 值就递增一(每个 RPC 请求在整个传输生命期内都保留有自己的 XID)。过多的重发请求对服务器产生了额外的压力,进一步使响应时间延长。如果 badxid 和 timeouts 的数目超过了总调用数的百分之五,可以用 smitty chnfsmnt 命令加大 NFS-mount 选项中的 timeo 参数。如果 badxid 是 0,is 0, 但 retrans 和 timeouts 相当大,可以尝试减少 NFS 缓冲区的大小(使用 mount 命令中的 rsize 和 wsize 选项)。

如果服务器是 CPU 绑定的(CPU-bound),NFS 和 它的守护进程会受到影响。要在这种情形下提高性能,服务器必须调优、升级或者用户可以让应用程序文件放置在本机上。如果服务器是 I/O 绑定的(I/O-bound),服务器文件系统可以被重新组织或者可以使用本地化的文件。

如果重发和超时的数目接近于同一个值时,可以确定包正在被丢弃。包很少在客户机端被丢弃。通常,包要么是在网络上被丢弃,要么是在服务器上被丢弃。 服务器可能在以下两种情况下丢弃包:当包从服务器接口驱动程序的发送队列中溢出时,或者当服务器的用户数据报协议(UDP)套接字缓冲区溢出时(nfs_socketsize)。如果在服务器上没有出现套接字缓冲区溢出 或 Oerrs ,同时客户机上又有许多的重发和超时,那么包可能就是在网络上被丢弃的。问题也许是出在传播媒介和网络设备上,比如路由器、桥接器或集线器。网络检漏器(network sniffer)以及其他的工具可被用来调试诊断这些问题。

在某些场合下,应用程序或用户经历了很差的性能,然而在用 nfsstat -c 命令检查时输出结果却显示超时和重发数目等于零或很少。这说明客户机从服务器接收响应的速度与请求的速度是一样快的。这时,首先要检查在客户机上运行的 biod 守护进程的数目是否适当的。该检查当一个应用程序正在锁定远程文件时仍然可测。当远程文件锁加在一个正服务于 NFS 的文件上时,客户机将关闭所有该文件在高速缓存上的数据和属性而转入一种完全同步的操作方式。结果就导致很慢的执行性能,不幸的是这种情况还十分的普遍。 包的锁定可以从 ipreport 的输出结果中通过查找 NLM 请求来识别。

nfsstat -m
nfsstat -m 命令显示服务器名、服务器地址、mount(挂载)标志、当前读写大小、重发次数和每个客户机上 NFS mount 的动态重发次数,如下:
# nfsstat -m
/SAVE from /SAVE:itsorus.austin.ibm.com
Flags:   vers=2,proto=udp,auth=unix,soft,intr,dynamic,rsize=8192,wsize=8192,retrans=5
Lookups: srtt=27 (67ms), dev=17 (85ms), cur=11 (220ms)
Reads:   srtt=16 (40ms), dev=7 (35ms), cur=5 (100ms)
Writes:  srtt=42 (105ms), dev=14 (70ms), cur=12 (240ms)
All:     srtt=27 (67ms), dev=17 (85ms), cur=11 (220ms)

上例输出结果中圆括号内的数字是实际时间,单位是毫秒。其他的值是操作系统内核保留维护的无单位的值。您可以忽略这些无单位的值。上例分别显示出了查找、读、写和所有这些操作组合在一起(All)的响应时间。输出中用到的其他定义如下:
srtt
平滑往返时间(smoothed round-trip time)
dev
估计偏差(estimated deviation)
cur
当前补偿超时值(current backed-off timeout value)

netpmon 命令
有关该命令及其输出的讨论请参见 netpmon 命令。

nfso 命令
nfso 命令用来配置 NFS 属性。可以设置或显示当前运行内核的网络选项。因此,这个命令必须在每个系统启动或网络配置后才能运行。
注:
nfso 命令并不进行范围检查。如果被不正确地使用,nfso 命令可能使您的系统无法工作。

nfso 的参数和各自的取值可以用 nfso -a 命令显示,如下:
(tremor:) # nfso -a
portcheck= 0
udpchecksum= 1
nfs_socketsize= 60000
nfs_tcp_socketsize= 60000
nfs_setattr_error= 0
nfs_gather_threshold= 4096
nfs_repeat_messages= 0
nfs_udp_duplicate_cache_size= 5000
nfs_tcp_duplicate_cache_size= 5000
nfs_server_base_priority= 0
nfs_dynamic_retrans= 1
nfs_iopace_pages= 0
nfs_max_connections= 1024
nfs_max_threads= 128
nfs_use_reserved_ports= 0
nfs_device_specific_bufs= 1
nfs_server_clread= 1
nfs_rfc1323= 1
nfs_max_write_size= 0
nfs_max_read_size= 0
nfs_allow_all_signals= 0
nfs_v2_pdts= 1
nfs_v3_pdts= 1
nfs_v2_vm_bufs= 1000
nfs_v3_vm_bufs= 1000
nfs_securenfs_authtimeout= 0
nfs_v3_server_readdirplus= 1

如果需要查阅有关这些属性的描述,请参见网络可调优参数。许多 NFS 属性是运行时属性(run-time attributes),它们是可以在任何时间被修改的。而要修改负载时属性(load time attributes),如 nfs_socketsize,就需要 NFS 先停下来而后再重新启动。

要显示或者修改一个指定的参数,可使用 nfso -o 命令,如下:
# nfso -o portcheck
portcheck= 0
# nfso -o portcheck=1

参数还可以重新设置成它们的缺省值,使用 -d 选项,如下:
# nfso -d portcheck
# nfso -o portcheck
portcheck= 0

NFS 参考
以下是与 NFS 有关的文件、命令、守护进程和子程序的摘要。需要详细信息,请参见 《AIX 5L V5.2 系统管理指南:通信与网络》 和 《AIX 5L V5.2 命令参考大全》。

网络文件系统(NFS)文件列表
以下是 NFS 文件列表,包括配置信息:
bootparams
列出了可以用来启动的无磁盘客户机
exports
列出了可以导出到 NFS 客户机的目录
networks
包含了因特网上的网络信息
pcnfsd.conf
为 rpc.pcnfsd 守护进程提供配置选项
rpc
包含了为远程过程调用(RPC)提供的数据库信息
xtab
列出了当前已经导出的目录
/etc/filesystems
列出了试图在系统重新启动时被 mount 的所有文件系统

NFS 命令列表
以下是 NFS 命令列表:
chnfs
启动指定数目的 biod 和 nfsd 守护进程
mknfs
配置系统使其运行 NFS 并且启动 NFS 守护进程
nfso
配置 NFS 网络选项
automount
自动 mount NFS 文件系统
chnfsexp
修改 NFS 导出(NFS-exported)目录的属性
chnfsmnt
修改 NFS 挂载(NFS-mounted)目录的属性
exportfs
导出目录到 NFS 客户机以及回收(unexport)目录
lsnfsexp
显示由 NFS 导出的目录特征
lsnfsmnt
显示已挂载(mounted)NFS 系统的特征
mknfsexp
使用 NFS 导出一个目录
mknfsmnt
使用 NFS 挂载一个目录
rmnfs
停止 NFS 守护进程
rmnfsexp
从服务器导出列表中删除 NFS 导出(NFS-exported)目录
rmnfsmnt
从客户机挂载列表中删除 NFS 挂载(NFS-mounted)文件系统

NFS 守护进程列表
以下是 NFC 锁定守护进程列表:

lockd
通过 RPC 包来处理锁定请求
statd
为 NFS 上的锁定服务提供崩溃恢复(crash-and-recovery)功能

以下是网络服务守护进程和实用工具的列表:
biod
发送客户机的读写请求至服务器
mountd
应答来自客户机的对文件系统的 mount 请求
nfsd
启动用以处理客户机对文件操作请求的守护进程
pcnfsd
处理来自 PC-NFS 客户机的服务请求
nfsstat
显示机器接收调用的性能信息
on
在远程机器上执行命令
portmap
将 RPC 程序端口号映射为因特网端口号
rexd
接收运行远程机器上程序的请求
rpcgen
生成 C 代码以实现一个 RPC 协议
rpcinfo
报告 RPC 服务器的状态
rstatd
返回从内核获得的性能统计信息
rup
显示本地网络上的一个远程主机的状态
rusers
报告已登录到远程机器上的用户列表
rusersd
响应 rusers 命令的请求
rwall
发送消息至网络上的所有用户
rwalld
处理 rwall 命令的请求
showmount
显示所有已挂载远程文件系统的客户机列表
spray
发送指定数目的包到一个主机
sprayd
接收由 spray 命令发来的包

以下是网络安全守护进程和实用工具列表:
chkey
修改用户的加密密钥(encryption key)
keyenvoy
提供用户进程与密钥服务器之间的中介
keylogin
解密并存储用户的密钥(secret key)
keyserv
存储公有和私有密钥
mkkeyserv
启动 keyserv 守护进程并将 /etc/rc.nfs 文件中适当的注释项改为非注释的
newkey
在公有密钥文件中创建一个新的密钥
rmkeyserv
停止 keyserv 守护进程并注释掉 /etc/rc。nfs 文件中为 keyserv 守护进程而设的项
ypupdated
更新网络信息服务(NIS)映象中的信息

以下是无磁盘客户机支持配置文件:
bootparamd
提供无磁盘客户机启动所需的信息

以下是 NFS 子程序列表:
cbc_crypt()、des_setparity() 或 ecb_crypt()
实现数据加密标准(DES)例行程序。


--------------------------------------
NFS 性能调优

在 NFS 网络中,服务器是调优的主要目标,当然也有一些是可以在客户机上调优的。
需要多少 biod 和 nfsd 守护进程?

因为 biod 和 nfsd 守护进程一次处理一个请求,并且 NFS 响应时间占了总响应时间的最大一部分,所以如果线程由于缺少 biod 或 nfsd 守护进程而阻塞是让人无法接受的。

注:只存在单一的 nfsd 守护进程和单一的 biod 守护进程,它们都是多线程的(多个内核线程在一个进程里)。此外,线程数是动调优的,会按需建立额外的线程。但是,您也可以通过使用 nfso 命令的 nfs_max_threads 参数来手动设置 nfsd 的最大线程数。您还可以利用 biod 命令的 mount 选项来调整每次 mount 时最大的 biod 线程数。

配置 NFS 守护进程一般需要注意的事项如下:
* 增加守护进程的数量并不能用来弥补客户机或服务器的处理器能力低下、内存不足以及服务器磁盘传输宽带的不足。在改变守护进程数量之前,您应该先用 iostat 和 vmstat 命令来检查一下服务器和客户机的资源利用级别。
* 如果 CPU 或 磁盘子系统已经接近于饱和级别,那么增加守护进程的数量并不会带来更好的性能。
* NFS 守护进程相对来说开销不大。biod 或 nfsd 守护进程只需要很少的几个内存页(其中有些是固定〔pinned〕的)。当然,没有被固定的(unpinned)页面仅当 nfsd 或 biod 守护进程最近被激活过时才真正存在于内存中。此外,空闲的 nfsd 或 biod 守护进程不耗费 CPU 时间。
* 所有的 NFS 请求都通过 nfsd 守护进程;但是只有读写操作才通过 biod 守护进程。

选择初始的 nfsd 和 biod 守护进程的数目
决定最佳的 nfsd 和 biod 守护进程数是反复的过程。指导方针能提供给您的仅仅是一个合理的出发点。

缺省值对于小型系统来说是一个很好的起点,但对于拥有两个以上客户的客户机系统或者拥有两个以上客户机的服务器来说就多半需要增加了。以下是一些指导方针:
* 在每个客户机上,估计将会发生并发写操作的最大文件数。为每个文件配置至少两个 biod 守护进程。如果文件比较大(大于 32KB),为了支持预读(read-ahead)或后写(write-behind)行为,您可能需要为每个文件启动四个 biod 守护进程。为一个很大的频繁进行写操作的文件配置五个 biod 守护进程也是很普遍的。
* 在每个服务器上,开始时把 nfsd 守护进程数配置成同已经为客户机从服务器处理文件的 biod 守护进程一样多的数量。考虑到非读写的 NFS 请求,在原先的基础上再加 20% 的数量。
* 如果您在一台慢速服务器上连有快速的客户机工作站,那么您必须限制客户机产生 NFS 请求的速率。最佳的解决方案是减少客户机上 biod 守护进程的数量,并对每个客户机负载和响应时间的相对重要性给予适当的关注。

nfsd 和 biod 守护进程数的调优
在您获得初始的 biod 和 nfsd 守护进程数量后,或已经修改了其中的某一个,请照以下说的做:

* 首先,用 vmstat 和 iostat 命令重新检查受影响系统的 CPU 或 I/O 饱和度。如果服务器现在就饱和了,您必须减少负载或增加处理器能力,也可以两者都满足。
* 使用命令 netstat -s 来判断是否有系统正在经历 UDP 套接字缓冲区溢出。如果确是那样的话,用命令 no -a 去证实一下调优其他层来提高 NFS 的性能 一小节中已经实现了的推荐方法。如果可行,系统没有饱和,就可以增加 biod 或 nfsd 守护进程的数量。
* 检查 nullrecv 列,给列位于命令 nfsstat -s 的输出结果中。如果这个数字开始增长,那便说明 nfsd 守护进程的个数太多了。然而,这种情况在我们的操作系统的 NFS 服务器上出现的概率比在其他平台上出现的概率要小得多。原因在于当有一个 NFS 请求进入服务器时,并不是所有的 nfsd 守护进程被同时唤醒。而是这样的,第一个 nfsd 守护进程被唤醒,如果还有更多的工作要做的话,由它再去唤醒第二个 nfsd 守护进程,以此类推。

要修改 nfsd 守护进程的数量,您可以使用 chnfs 命令,或者如前所述设置 nfso nfs_max_threads 参数。

要把在服务器上的 nfsd 守护程序的数量修改为 10,既要立刻生效又要在以后的系统启动时也生效,使用如下命令:
# chnfs -n 10

要把一个系统上的 nfsd 守护进程的数量改为 9,需要直到下一次系统启动才生效,使用如下命令:
# chnfs -I -n 9

要修改每次挂载(mount)的 biod 守护进程数,可使用 biod mount 选项。

增加客户机上的 biod 守护进程数使服务器性能变坏,因为这将允许客户机一次发送更多的请求,而进一步增加网络和服务器的负载。极端情况下,客户机的运行速度远远超过服务器,这时可能需要将客户机的 biod 守护进程数减少到一个,如下:
# stopsrc -s biod

这使得客户机仅仅留下一个 biod 内核进程仍然继续运行。

硬 NFS 挂载(hard NFS mounts)或软 NFS 挂载(soft NFS mounts)的性能推断
当您在配置 NFS 挂载目录时有一个可选项就是:挂载或是硬的(-o hard)或是软的(-o soft)。在成功的挂载后,当一个对软挂载(soft-mounted)目录的访问出错时(典型的是一个超时),这个错误被立即报告给原先请求远程访问的那个程序。当一个对硬挂载(hard-mounted)目录的访问出错时,NFS 重试原来的操作。

一个持久性错误引起的不断访问硬挂载目录可能会升级成为一种能察觉得到的性能问题,因为缺省的重试次数是 1000 次,缺省的超时值是 0.7 秒,再加上有一个算法使连续的重试间的超时值增加,这一切意味着 NFS 将试图去完成这个操作。

减少重试次数、增加超时值,或者前两者都做到,这在技术上是可能的,只要使用 mount 命令的选项。不幸的是,修改这些值虽然足以去除先前对性能的可察觉的影响,但是有可能会导致不必要的硬件错误报告。作为一种替代,可以使用 intr 选项来 mount 硬挂载目录,这时当有某个进程进入了重试循环则允许用户使用键盘将其中断。

虽然软挂载目录引起的错误可以被更快地探测到,但是它要冒严重的数据毁坏的风险。因此一般来说,读/写目录应该用硬装载。

其他影响性能的 mount 选项
mount 命令提供了一些 NFS 调优的选项,但由于缺乏对它们的了解而经常被忽视或错误地使用。

在您开始调节 mount 选项前,请确认您应该达到对服务器或网络上的包传送(packet delivery)和包转向(packet turnaround)有一定的认识。如果您的目标是降低 NFS 服务器的负载或者是要解决与网络相关的问题,那么您将会使用绝大部分 NFS 所特有的 mount 选项。

用 mount 命令的 -o 选项可以列出与 NFS 性能相关的所有特定的 mount 选项。-o 选项在命令行中只需用一个逗号与命令分隔,而不是用一个逗号加一个空格分隔。

rsize 和 wsize 选项
最有用的是改变读和写操作大小值的选项。这些选项定义了每个 RPC 读和写的最大尺寸。mount 命令的 rsize 和 wsize 选项常常被减小以减小发向服务器的读/写包。您为什么要减小这两个选项值呢?有两个原因:

1. 服务器可能会没有能力处理传输读/写包(NFS V2 是 8KB,NFS V3 是 32KB)所带来的数据容量和速度。一个例子就是如果 NFS 客户机使用一台 PC 作为 NFS 服务器。这台 PC 将很可能只有有限的内存可用于缓冲大的包。
2. 如果读/写尺寸被减小了,随之带来的就是由调用产生的 IP 片断(IP fragment)数量的减少。如果您正在使用的是一个有损网络,要完成一次同样的调用/应答对,只用两个包交互比必须分用七个包交互成功的概率更大。同 样的,如果你在复合网络上发送 NFS 包,而这些网络本身又有不同的性能特征,此时还要求所有的包片断在小于 IP 片断超时值的时间内到达是不太现实的。

减小 rsize 和 wsize 可以在一个比较拥塞的网络上通过向每个 NFS 请求发送较短的包列,从而提高 NFS 性能。但是带来一个副作用,就是需要更多的包在网络上发送数据,增加了网络的通信量,同时在服务器和客户机上都增加了 CPU 的开销。

如果您的 NFS 文件系统是通过一个高速网络挂载的,如 SP Switch,则较大的读/写包能提高 NFS 文件系统的性能。在 NFS V3中,rsize 和 wsize 可以设置最大至 65536,缺省值是 32768。 在 NFS V2 中,rsize 和 rsize 最大可以达到 8192,同时这也是缺省值。

提高连续 I/O 吞吐量
在 AIX 5.1 及更新的系统中,您可以通过一种叫延迟释放(release-behind)的机制来提高对位于 NFS 导出文件系统上的大文件的连续 I/O 操作的性能。更多有关延迟释放的信息,请参见文件系统的监视和调优。

提高客户机大文件 I/O 吞吐量
在 NFS V3 上的特例中,您试图对一个比客户机内存还要大的文件进行连续写操作,这时您可以使用延迟提交(commit-behind)来提高性能。在通常情况下,写 一个大文件会在客户机上引起频繁的页面交换动作。这就使得提交(commit)操作在同一时刻只能执行一个页面。延迟提交给出了一个更具挑战性的逻辑,即 将客户机页面提交和返回那些页面到没有任何开销的表(free list)。

您可以在挂载文件系统时指定 combehind 标志 来打开延迟提交功能,该标志在 mount 命令中使用。您还需要为 numclust 变量设置一个适当的值。这个变量指定了虚拟内存管理(VMM)的连续延迟写算法所处理的 16KB 群集的数量。当 I/O 模式是连续的时,使用一个较大的 numclust 值以便能在为它们做 I/O 调度前在内存中保留更多的页面。如果条带化的逻辑卷或磁盘阵列正被使用则需要增大 numclust 值。在 AIX 5.1 上,这个参数可以作为 mount 的一个选项被指定。在 AIX 的早先版本中,使用 vmtune 命令来指定 numclust 的值。

禁用未被使用的 NFS ACL 支持
如果您不使用在导出文件系统中支持的 NFS 访问控制列表(ACL),那么您可以通过指定 noacl 选项从一定程度上减轻客户机和服务器上的工作负载。如下操作:
options=noacl

将这个选项设置成客户机上的 /etc/filesystems 中的有关文件系统那一段中的一部分。

调优以避免重发
硬挂载和软挂载两者哪个更好,这个问题关键在于要在一个给定的网络配置上寻求合适的超时持续时间。如果服务器超负荷运行,与客户机之间隔着一个或多 个网桥、网关,又或者通过一个广域网(WAN)与客户机相连,则此时缺省的超时标准就显得不切实际了。如果是这样的话,服务器和客户机都将负荷不必要的重 发。例如,命令如下:
# nfsstat -c

报告 timeouts 和 badxids 都是一个很大的数字(大于总数的 5%),您可以增加 timeo 参数,利用以下 SMIT 快捷路径:
# smitty chnfsmnt

定位到您想要改变的那个目录,并在 NFS TIMEOUT 行上输入新的值,以十分之一秒为单位。

缺省值是 0.7 秒(timeo=7),但是该值是由 NFS 内核扩展(NFS kernel extension)根据调用的类型来调整的。例如,对于读调用,该值被加倍成 1.4 秒。

为了对 V4(第四版)的客户机操作系统上的 timeo 值进行控制,您必须把 nfso 命令中的 nfs_dynamic_retrans 选项设置为 0。您有两种方法可以修改 timeo 值,但是在任何给定的情形下,仅有一种正确修改的方法。将超时值延长还是缩短,哪种是正确的方案这取决于包没有在已分配的时间内到达的原因。

如果包仅仅是晚到了一些但最终还是到达了,那么您或许应该将 timeo 变量改得更长一些,这样能在请求重发之前使应答有机会能返回。

然而,如果包被丢弃了则永远不会到达客户机,那么用再长的时间等待响应也只能是浪费时间,这时您应该想到将 timeo 变量改短。

可以评估到底使用哪个选项的一种方法是在客户机上查看 nfsstat -cr 的输出结果,看一看客户机是否报告存在很大的 badxid 数目。badxid 值表示某个 RPC 客户机接收到一个其他不同调用的 RPC 调用响应,而非原本应该收到的响应。一般情况下,这意味着客户机收到的是一个先前重发过的调用的重复应答。因而包就到达得晚了,应该让 timeo 值变长。

另外,如果您手头有网络分析仪,就可以用它来测定到底发生了两种情况中的哪一种。即使没有该仪器,您也可以通过试探性地把 timeo 选项调高调低来哪一种提供了更好的总体性能。在一些情形下,运行状态并不是始终如一的。您的最优选择就是找出包延迟/包丢弃的真正原因并解决实际的问题,而问题一般就在服务器设备或网络设备上。

对于由网桥连接起来的两个局域网(LAN-to-LAN)上的流量来说,可以试着将值设成 50(单位:十分之一秒)对于广域网(WAN)连接,尝试 200。至少等上一天后再来检查 NFS 的统计信息。如果信息指示仍然有过多的重发,则将 timeo 增加 50% 后重试。您还要注意检查服务器工作负载以及所涉及到的网桥和网关上的负载,察看它们中的任何一个是否被其他的流量占用而趋于饱和。

丢弃的包
假设 NFS 客户机已经检测到有包被丢弃,此时具有挑战性的工作是去发现这些包是在哪里丢失的。包可以被客户机丢弃,可以被服务器丢弃,也同样可以在网络上的某个地方被丢弃。

包被客户机丢弃
包很少被客户机丢弃。因为每一个 RPC 调用都是自步长的(self-pacing),也就是说每个调用在继续下一步前必须获得应答,过度使用系统系统资源的几率是微乎其微的。压力最大的操作大 概就是读操作了,读的时候可能会达到 1MB/sec 以上进入机器的数据流量。虽然数据容量可以很大,但实际可以并发 RPC 调用数相当的少而且每个 biod 守护进程都有为应答分配的自己的地址空间。因此,包被客户机丢弃是很罕见的。

通常情况下,包要么是被服务器丢弃,要么是在网络上被丢弃。

包被服务器丢弃
服务器在繁重的负载下将会丢弃包,存在两种情况:

1. 适配器驱动程序(Adapter Driver)
当 NFS 服务器在对很多请求进行响应时,有时会从接口驱动程序输出队列中溢出。您可以使用 netstat -i 命令来观察所列出的统计信息。检查标记为 Oerrs 的那列,可以看到一些值。每一个 Oerrs 就是一个被丢弃的包。这可以方便地来调优,就是把出问题的那个设备的驱动程序传输队列长度增加。在配置可调队列长度时的思路就是:尽量不要使传输队列过 长,因为如果队列过长的话在处理队列时就会有一定的延迟。但是因为 NFS 为调用维护了相同的端口号和 XID,第二次的调用可以用第一次调用的响应来满足。另外,队列处理延迟比在丢包的情形下由 NFS 引起的 UDP 重发延迟要小得多。

2. 套接字缓冲区
服务器丢包的第二个常见的地方是 UDP 套接字缓冲区。被丢弃的包在这里由 UDP 层来计数,使用 netstat -p udp 命令可以显示相关的统计信息。其中标记为 UDP: 的就是套接字缓冲区溢出 信息。

通常情况下,仅当服务器有很多 NFS 写流量时 NFS 包才在套接字缓冲区中被丢弃。NFS 服务器使用一个与 NFS 2049 端口捆绑的 UDP 套接字,所有的输入数据都在这个 UDP 端口被缓冲。这个缓冲区的缺省大小是 60,000 字节。您可以做一个简单的除法:缓冲区大小除以单个写包(write packet)的大小,每个 NFS 写包的缺省大小是 8192 字节,很显然对于缺省大小的缓冲区只要有八个同时到达的写包就已经溢出了。仅仅是两个 NFS 客户机(缺省配置下)就会出现溢出。

这种情况中,套接字上要么是有大容量的流量,要么就是有高突发性的流量。
* 如果是高容量的流量,混合有写流量和其他非写的 NFS 流量,这时 nfsd 守护进程可能会跟不上那个容量而来不及将数据从套接字上取走。需要重新唤醒专门的 nfsd 守护进程来为各类的 NFS 调用服务。
* 在遇到高突发性的流量时,已经存在的 nfsd 守护进程数应该是足够了,但由于流量是突发性的,因此在很短的瞬间内有很多包到达,以至于套接字还没有被唤醒包就已经溢出了。

这两种情况的解决方法是不同的。
* 在高容量情况下,只增加系统上运行的 nfsd 守护进程数就足够了。因为增加 nfsd 守护进程数并不会为机器带来显著的负面影响,因此可以先试着用一下这个解决方案。另外,请参见需要多少 biod 和 nfsd 守护进程?
* 在高突发性流量的情况下,唯一的解决方案就是加大套接字,希望能以合理的大小为 nfsd 守护进程提供更多的时间来处理突发的流量。为这种套接字分配的专用内存不会被用于其他用途,所以需要注意的是:利用增大套接字的方法消除套接字缓冲区溢出 以达到调优的目标,这将使已分配的内存在大部分时间内被占用。一个谨慎的管理员会观察套接字缓冲区溢出的统计信息,将其与性能问题联系起来,并决定采用多 大的套接字缓冲区。有关怎样操控 NFS 套接字缓冲区的详细情况请参见增加 NFS 套接字缓冲区的大小。

您可能还会遇到以下情况:当服务器已被调优且既没有在套接字缓冲区上丢包也没有在适配器驱动程序上的 Oerrs 错误信息,但是客户机仍然在经历超时和重发。这里再次分为了两种情形。如果服务器负载繁重,可能服务器刚刚在超负载运行而现在 nfsd 守护进程在执行日志回写(backlog)工作,导致响应时间超过了客户机上设置的缺省超时值。请参见 NFS 调优核对清单获取提示以便确认问题是否在此。另一种可能性,如果服务器是空闲的,那么包就是在网络上被丢弃的。

包在网络上被丢弃
如果服务器上既没有套接字溢出,也没有 Oerrs 错误信息,而客户机又有很多超时和重发且服务器已知是空闲的,则包很可能是在网络上被丢弃的。牵涉到网络的问题意味着什么呢?意味着很多传播媒介和网络设备,诸如路由器、网桥、集线器和所有那些为使包能在客户机和服务器间实现传输的设备。

当服务器没有超负载且没有丢包,但 NFS 性能差的时候,都可以认为包是在网络上被丢弃的。再努力一下就可以进一步证明这一点并且发现网络究竟是怎样把包给丢弃了。最简便的方法很大程度上取决于物理上的邻近性和可用的资源。

有时服务器和客户机物理上十分接近,使得直接连接非常的容易,而如果要穿越较大的网段就可能引发问题。很显然,如果把两台机器直接相连可以解决原先 的问题的话,那么就可以排除问题是由于机器本身原因造成的了。可是在常见的情况下,直接连接又不太可能,因此问题还是必须在适当的位置才能被捕获。

调优 NFS 文件属性高速缓存
NFS 在每个客户机系统上为最近被访问过的目录和文件维护一个高速缓存。在 /etc/filesystems 文件中有五个参数可设置,用来控制某个指定条目在高速缓存中要保留多久。这些参数如下:

actimeo
在文件和目录条目被更新后,要在文件属性高速缓存中保留的绝对时间。如果被指定,则该值会覆盖 *min 和 *max 的值,事实上把它们都设成了 actimeo 的值。
acregmin
在文件条目被更新后,保留的最短时间。缺省值是 3 秒。
acregmax
在文件条目被更新后,保留的最长时间。缺省值是 60 秒。
acdirmin
在目录条目被更新后,保留的最短时间。缺省值是 30 秒。
acdirmax
在目录条目被更新后,保留的最长时间。缺省值是 60 秒。

每次文件或目录被更新后,从高速缓存中移除至少要等 acregmin 或 acdirmin 秒。如果是第二次或后续的更新,条目最多被保留的时间至少等于最近两次更新之间的间隔时间,但是不会超过 acregmax 或 acdirmax 秒。

CacheFS 不执行什么
CacheFS 不会提高 NFS 文件系统的写操作性能。但是当挂载 CacheFS 时,在 mount 命令的 -o 选项中为您提供了两个写操作选项。它们会影响后续对数据读操作的性能。写操作选项如下:
write-around
write-around 模式(缺省)与 NFS 处理写操作的方式是一样的:写操作写入后台文件系统,被写的文件从高速缓存中被清除出去。这意味着 write-around 使高速缓存无效,写操作执行后新数据必须从服务器取回。
non-shared
当确信不会有人往高速缓存文件系统内写数据时,可以采用 non-shared 模式。在此模式下,所有的写操作既写入前台文件系统又写入后台文件系统,并且文件仍然留在高速缓存。这就意味着以后的读访问可以到高速缓存中来执行,而不需要去访问服务器。

有一些小的读操作可能总是保留在内存中(根据您对内存的使用状况),此时即使将数据缓存在磁盘上也不会带来什么益处了。缓存随机读操作所读的不同数据块是没有意义的,除非您要对同一数据反复地访问。

初始的读请求还是必须发到服务器上去,因为只有当某个用户对后台文件系统上的部分文件进行过访问后,那些文件才会出现在高速缓存中。对于初始的读请求,您将感受到的是普遍的 NFS 速度。只有对同一数据的后续访问您才会感受到本地 JFS 访问的性能。

对于缓存数据的一致性仅仅是隔一段时间才检查一次。因此缓存经常被修改的数据是危险的。CacheFS 应该仅仅 被用于只读(read-only)数据和可改写只读(read-mostly)数据。

NFS v2 和 NFS v3 在高速缓存文件系统上的写操作性能是不同的。性能测试显示:
* 对于在 NFS v2 上的一个新文件进行连续的写操作,写入 CacheFS 挂载点(mount point)比直接写入挂载点要慢百分之二十五。
* 同样的情形,对于在 NFS v3 上的一个新文件进行连续的写操作,写入 CacheFS 挂载点比直接写入挂载点要慢六倍。

配置 CacheFS
CacheFS 并不是缺省被实现的,也不是在创建 NFS 文件系统后就启动的。为了在 AIX 4.3.1 上获得增强的 CacheFS 写性能请确认安装:文件集级别(fileset level)4.3.1.1。

系统管理员必须显式地指定哪个文件系统将被挂载到高速缓存中,如下:

1. 使用 cfsadmin 命令创建本地高速缓存文件系统:
# cfsadmin -c -o 参数 高速缓存目录
上面的参数 特指资源参数,高速缓存目录 是指将高速缓存创建到那个目录的目录名。

2. 将后台文件系统挂载到高速缓存中:
# mount -V cachefs -o backfstype=nfs,cachedir=/ 高速缓存目录  remhost:/远程目录 本地挂载点
上面的远程目录 指数据所在的远程主机和文件系统名,本地挂载点 指远程文件系统应该在客户机上的哪个挂载点挂载。

3. 另外,您还可以使用 SMIT 命令(用 smitty cachefs 快捷路径)来管理 CacheFS。

一些参数可以在 CacheFS 创建时被设置,如下:
maxblocks
设置在前台文件系统内 CacheFS 被允许申请的最大块数。缺省值 =90%。
minblocks
设置在前台文件系统内 CacheFS 被允许申请的最小块数。缺省值 =0%。
threshblocks
设置一个块数,它指定了在 CacheFS 申请多于 minblocks 数目的块之前必须分配给客户机一端的 JFS 文件系统的块数。缺省值 =85%。
maxfiles
CacheFS 所能使用的最大文件数,以前台文件系统中的 i-node 总数的百分比形式表达。缺省值 =90%。
minfiles
CacheFS 始终被允许使用的最小文件数,以前台文件系统中的 i-node 总数的百分比形式表达。缺省值 =0%。
maxfilesize
CacheFS 允许缓存的最大的文件大小,单位:兆字节(MB)。缺省值 =3。

NFS 的 RPC 调优
rpc.lockd 守护进程是多线程的,缺省时最多可以创建 33 个线程。在 RPC 文件锁定性为频繁发生的情况下,当 rpc.lockd 守护进程一旦达到它的最大线程数时,它就可能成为一个瓶颈。当达到最大线程数时,任何后续的请求都将等待,这会导致其他的超时。如果存在多于一个的客户机,则 NFS 服务器应该比客户机有更多的 lockd 线程。lockd 线程数可以调整为最大不超过 511 的值,如下:
# chsys -s rpc.lockd -a
# stopsrc -s rpc.lockd; startsrc -s rpc.lockd

调优其他层来提高 NFS 的性能

NFS 使用 UDP 或 TCP 来执行网络 I/O。请确保您已经应用了在调优 TCP 和 UDP 性能 和调优 mbuf 池的性能这两部分中所介绍的调优技术。特别地,您应该:
* 确保 LAN 适配器发送接收队列长度都被设置为最大(请参见适配器发送与接收队列调优)。
* 增大套接字缓冲区大小的最大值(sb_max)为至少 131072 字节。如果 MTU 大小不到 4096,至少设置 sb_max 值为 262144。另外再设置 UDP 套接字缓冲大小(udp_sendspace 和 udp_recvspace)为 131072 字节。如果您使用的是 TCP,设置 tcp_sendspace 和 tcp_recvspace 为 131072 字节。
* 如果可能的话,增大局域网上的 MTU 大小。在一个 16 Mb 的令牌环网(Token-Ring)上,例如将 MTU 大小从缺省的 1492 字节改为 8500 字节就允许一整个 8KB 的 NFS 读或写请求一次性传输而不需要分段。它还更为有效地利用了 mbuf 地址空间,减小了超载的可能性。
* 一个可调的参数:nfs_tcp_socketsize 给出了在 NFS 连接下 TCP 端口的缺省窗口大小。无论有多少个挂载,在每个客户机和服务器之间仅有一个连接。不要将 nfs_tcp_socketsize 的值设置为小于 60,000 的值。大型的或繁忙的服务器应该有较大的值,直到命令 netstat -s -p tcp 的输出结果中 TCP NFS 流量显示没有丢包。
* 允许连入服务器的最大 TCP 连接数可以被新的选项 nfs_max_connections。所控制。缺省值是 0,表示没有限制。客户机会关闭空闲时间超过五分钟的 TCP 连接,当用户授权时连接可以被重新建立。服务器会关闭空闲时间超过六分钟的连接。
* 操作系统提供了一个用于关闭 NFS 所独有的 UDP 和校验(checksum)功能的选项。您可以使用 nfso 命令中的选项,称之为 udpchecksum。缺省值为 1(和校验功能有效)。当关闭这个功能后可以有一点点性能的提升,这是以增大数据损坏几率为代价的。

增加 NFS 套接字缓冲区的大小
在调优 UDP 的过程中,您可能会发现命令 netstat -s 显示有大量的 UDP 套接字缓冲区溢出。作为一般的 UDP 调优,增大 sb_max 值。您还需要增大 nfs_socketsize 值,这是用来指定 NFS 套接字缓冲区大小的。例如:
# no -o sb_max=131072
# nfso -o nfs_socketsize=130972

上例顺次增加 sb_max 的值,每次比 nfs_socketsize 所期望的值大至少 100 字节,并且将 nfs_socketsize 设置为 130972。

注:在 AIX V4 中,套接字大小是动态设置的。使用 no 和 nfso 命令所作的配置在每次机器启动时必须再作一遍。您最好将它们加入到 /etc/rc.net 或 /etc/rc.nfs 文件中去,恰在 nfsd 守护进程启动前在 biod 守护进程启动后。加入的位置是十分重要的。

NFS 服务器磁盘配置
承受高密度写操作的 NFS 服务器能从下面的方法中受益:将日志逻辑卷与数据卷分开而放在一个单独的物理卷上。更详细的信息请参见磁盘安装前的指南。

通常情况下,数据访问需要有很高的并行性。多个客户机或者一个客户机的多个进程对服务器上的单个文件系统的并发访问会导致某个特定设备上的磁盘 I/O 成为瓶颈影响吞吐量。您可以使用 iostat 命令来估计磁盘负载。

对于大型的 NFS 服务器,常规策略是将磁盘 I/O 需求平均且最大限度地分配给多个磁盘和磁盘适配器。这样就能获得更大的并发性以及有能力运行更多的 nfsd 守护进程。在一个磁盘 I/O 有良好分布的系统上,可能会调整到一个状态,在这一状态上 CPU 负载成为服务器性能的限制因素。

滥用 NFS 对性能的影响
很多对 NFS 的滥用发生于下面的情形中:由于人们没有意识到他们要访问的文件是在网络的另一端,要访问这些文件需要消耗昂贵的通信代价。有一些这样的例子,如下:

* 在一个系统上的应用程序对 NFS 已挂载的库存文件做随机的更新,以此来支持另一个实时的零售现金登记应用程序。
* 一个开发环境中,每个系统上的源代码目录都被 NFS 挂载到该环境中其余的系统上,以使开发人员可以登录到任意系统上去编辑和编译工作。这在事实上保证了所有的编译既可以从远程系统中获取源代码又可以将输出写回远程系统。
* 在一个系统上运行 ld 命令来传输在 NFS 已挂载目录里的 .o 文件到同一目录里的 a.out 文件。
* 应用程序发出的写操作没有页面对齐(page-aligned)(例如 10KB)。写操作的大小小于 4 KB 总是引起页面调进(pagein)且在 NFS 下这个页面调进会进入网络。

可能有人会说这些是对 NFS 所提供的透明性的正确使用。也许的确如此,但是这些使用方法通用同样消耗了处理器时间、局域网带宽并延长了响应时间。当一个系统配置将 NFS 访问作为标准操作模式的一部分时,设计者应该在迎来技术或商务上的优势的同时,做好准备来抵御由此带来的资源过度消耗。

* 将所有的数据或源代码放到一个服务器上,而不是放到单独的一个工作站上,改善了源代码的控制并简化了集中性的备份。
* 一些不同的系统要访问相同的数据,这时使用一个专用的服务器比一个或多个担任客户机服务器双重角色的系统来得更有效率。

另一种不应该在 NFS 文件系统上运行的应用程序类型是那些每秒钟调用上百次 lockf() 或 flock() 的应用程序。在 NFS 文件系统上,所有的 lockf() 或 flock() 调用(和其他锁定调用)都必须通过 rpc.lockd 守护进程。这会严重降低系统性能,因为 lockd 守护进程可能无法在一秒钟内处理上千个锁定请求。

无论客户机和服务器的性能容量再怎么大,所有涉及到 NFS 文件锁定的操作会导致让人无法容忍的慢速。这在技术上可以用很多原因来解释,但所有的原因都基于一个事实,那就是如果一个文件被锁定,势必要花更多的开销 用于在读写时对文件的同步进行处理。这意味着客户机上不能缓存有任何的文件数据,包括文件属性。所有的文件操作变为完全同步模式而没有了缓冲。如果在 NFS 上运行的一个正在进行网络文件锁定的应用程序显示出很差的性能,甚至比运行在同样的客户机/服务器对上的其他应用程序性能还差,这是令人难以相信的。

NFS 调优核对清单

以下是一张核对清单,您可以顺着它一步步对 NFS 进行调优:
1. 查看您的服务器是否超负载运行。
常规的方法是减慢客户机速度观察是否会增加服务器的性能。以下方法可以各自单独使用:
* 在挂载时尝试仅使用一个 biod 守护进程。
在受影响的客户机上尝试仅使用一个 biod 守护进程。如果性能改善了,则可知是在网络或服务器上超载。运行 stopsrc -s biod 命令以停止所有的 SRC biod 守护进程。会留下一个内核进程 biod ,有了它您的系统还能够继续运行。观察在仅有一个 biod 进程的情况下,运行速度是否快些了。如果没有效果,则重新启动 biod 守护进程,请用 startsrc -s biod 命令。如果运行得快些了,请尝试着去判断当所有守护进程运行时包是在哪里被丢弃的。网络、网络设备、慢速服务器、超载服务器或没有很好调优的服务器都可能引发这个问题。
* 尝试减小读/写大小,并观察速度是否加快。
* 如果您使用的是 UDP,尝试用一下 TCP 挂载来替换。

2. 检查 Oerrs。
这是影响 NFS 服务器的几乎是最普遍的从属于配置的错误。
如果存在任何的 Oerrs ,为网络设备增大发送队列长度。这个操作可以在机器运行时进行,但是在修改(rmdev -l)。前接口必须被分离。您无法在一个无磁盘机器上关闭接口,而且您也没有特权当别的工作仍在进行时关闭接口。这种情况下,您可以使用 chdev 命令将修改保存在 ODM 中,这样的话在下一次启动后就能生效了。第一次时将当前的队列长度值加倍,重复这个过程(以后每次加 30)直到没有 Oerrs 报告为止。在 SP2 系统上,NFS 被配置为要穿越高速交换机,当发生了一个交换机错误或交换机暂时不可用时由于交换机的原因可能会产生 Oerrs。每一次试图发送到交换机的失败都被累加到 Oerr 上。这些错误数不能被消去。

3. 查找任何错误。
任何一个很大的值都暗示了问题的存在。

4. 检查 NFS UDP/TCP 缓冲区溢出。
当使用 UDP 时,NFS 服务器上的缓冲区溢出是另一个经常需要为 NFS 服务器来配置的问题。TCP 套接字同样可以在十分繁忙的机器上溢出。对两者的调优基本一致,所以本节仅讨论 UDP。

运行 netstat -s 命令并检查 UDP 统计信息中的套接字缓冲区溢出统计。如果是一个不为 0 的数,则您的 NFS UDP 缓冲区很可能是溢出了。但是,考虑到 UDP 套接字缓冲区丢包数是对整个机器的计数,丢掉的包有可能是 NFS 包也有可能不是。如果您要想确认那个计数指的是 NFS 包,则可以将客户机上的丢包数(通过命令 nfsstat -cr 显示)与在执行 NFS 写测试时的服务器套接字缓冲区溢出关联起来。

套接字缓冲区溢出会在有繁重压力的服务器上发生或在相对于客户机来说较慢的服务器上发生。少于 10 个的套接字缓冲区溢出并不是什么问题。但是上百个溢出就有点问题了。如果在您观察时这个数值还在不断增大,且 NFS 正好存在性能问题,则 NFS 需要调优。

两个因素可以被用来调优 NFS 套接字缓冲区的溢出问题。第一,尝试增加服务器上运行的 nfsd 守护进程的个数。如果那样并不解决问题,则您必须调节两个内核变量:sb_max(最大套接字缓冲区大小)和 nfs_socketsize (NFS 服务器套接字缓冲区大小)。使用 no 命令可以增加 sb_max。使用 nfso 命令增加 nfs_socketsize 变量的值。

sb_max 参数的值必须要大于 nfs_socketsize. 在这里很难提供新的建议值。最佳值就是一方面最小,另一方面可以使 netstat 报告 0 或仅产生少量的套接字缓冲区溢出。

请记住,在 AIX V4 中,套接字的大小是动态设置的。使用 no 和 nfso 命令所作的配置在每次机器启动时必须再作一遍。您最好将它们加入到 /etc/rc.nfs 文件中去,恰在 nfsd 守护进程启动前在 biod 守护进程启动后。加入的位置是十分重要的。

5. 检查 mbuf 的问题。
观察是否有 mbufs 请求被拒绝或被延迟。如果是的话,增加网络可用 mbuf 的数量。更详细的关于调优以消除 mbuf 问题的信息,请参见调优 mbuf Pool 池的性能。

6. 检查很小的网间包延迟。
很少有例子是由此引起的机器问题。如果在服务器和客户机之间有路由器或其他硬件,则您可以查阅它们的文档,看一下网间包延迟是否可以配置。如果可以,则尝试加大延迟。

7. 检查传播媒介是否匹配。
当包在两个速度差异很大的传播媒介中传送时,路由器可能会将由高速网发来的包丢弃,并试图从慢速网上抓取包。特别地,一个路由器试图从 FDDI 光纤网上的服务器取包并将这些包发送到位于以太网上的客户机。 向以太网发送包的速度显然不能跟上 FDDI 的速度。唯一的解决方案是尝试去减少客户机的请求量、使用更小的读/写大小和限制可用于单个文件系统的 biod 守护进程。

8. 检查 MTU 不匹配。
运行 netstat -i 命令并检查客户机和服务器上的 MTU。如果它们不同,则试着将它们改成同一个数看问题能否消除。另外要注意机器间的慢速或广域网、路由器或网桥,这些都可能在不同网段中传输时进一步分段。试着确定源与目的之间的最小 MTU,在 NFS mount 命令中修改 rsize/wsize 为某个小于 MTU 最小公分母的数。

9. 检查路由问题。
使用 traceroute 命令来查看无法预料的路由转发或延迟。

10. 检查错误日志。
运行 errpt 命令来查看网络设备或网络传输媒介的问题报告。还要寻找任何影响在导出文件系统上的 NFS 服务器性能的磁盘错误。

--------------------------------------
nfs优化总结
1.设置块大小
mount命令的risize和wsize指定了server端和client端的传输的块大小。
mount -t nfs -o rsize=8192,wsize=8192,timeo=14,intr client:/partition /partition
如果未指定,系统根据nfs version来设置缺省的risize和wsize大小。大多数情况是4K对于nfs v2,最大是8K,对于v3,通过server端kernel设置risize和wsize的限制。

vi /usr/src/linux2.4.22/include/linux/nfsd/const.h
修改常量: NFSSVC_MAXBLKSIZE

所有的2.4的的client都支持最大32K的传输块。系统缺省的块可能会太大或者太小,这主要取决于你的kernel和你的网卡,太大或者太小都有可能导致nfs速度很慢。

具体的可以使用Bonnie,Bonnie++,iozone等benchmark来测试不同risize和wsize下nfs的速度。当然,也可以使用dd来测试。
#time dd if=/dev/zero of=/testfs/testfile bs=8k count=1024  测试nfs写
#time dd if=/testfs/testfile of=/dev/null bs=8k        测试nfs读

测试时文件的大小至少是系统RAM的两倍,每次测试都使用umount 和mount对/testfs进行挂载,通过比较不同的块大小,得到优化的块大小。

2.网络传输包的大小
网络在包传输过程,对包要进行分组,过大或者过小都不能很好的利用网络的带宽,所以对网络要进行测试和调优。可以使用ping -s 2048 -f hostname进行ping,尝试不同的package size,这样可以看到包的丢失情况。同时可以使用nfsstat -o net 测试nfs使用udp传输时丢包的多少。因为统计不能清零,所以要先运行此命令记住该值,然后可以再次运行统计。如果经过上面的统计丢包很多。那么可以看看网络传输包的大小。使用下面的命令:
#tracepath node1/端口号
#ifconfig eth0

比较网卡的mtu和刚刚的pmtu,使用#ifconfig eth0 mtu 16436设置网卡的mtu和测试的一致。当然如果risize和wsize比mtu的值大,那么的话,server端的包传到client端就要进行重组,这是要消耗client端的cpu资源。此外,包重组可能导致网络的不可信和丢包,任何的丢包都会是的rpc请求重新传输,rpc请求的重传有会导致超时,严重降低nfs的性能。
可以通过查看:
/proc/sys/net/ipv4/ipfrag_high_thresh
/proc/sys/net/ipv4/ipfrag_low_thresh

了解系统可以处理的包的数目,如果网络包到达了ipfrag_high_thresh,那么系统就会开始丢包,直到包的数目到达ipfrag_low_thresh。

3.nfs挂载的优化
timeo:如果超时,客户端等待的时间,以十分之一秒计算
retrans:超时尝试的次数。
bg:后台挂载,很有用
hard:如果server端没有响应,那么客户端一直尝试挂载
wsize:写块大小
rsize:读块大小
intr:可以中断不成功的挂载
noatime:不更新文件的inode访问时间,可以提高速度
async:异步读写

4.nfsd的个数
缺省的系统在启动时,有8个nfsd进程
#ps -efl|grep nfsd
通过查看/proc/net/rpc/nfsd文件的th行,第一个是nfsd的个数,后十个是线程是用的时间数,第二个到第四个值如果很大,那么就需要增加nfsd的个数。
具体如下:
#vi /etc/init.d/nfs

找到RPCNFSDCOUNT,修改该值,一般和client端数目一致。
#service nfs restart
#mount -a

5.nfsd的队列长度
对于8个nfsd进程,系统的nfsd队列长度是64k大小,如果是多于8个,就要相应的增加相应的队列大小,具体的在
/proc/sys/net/core/rwmem_default
/proc/sys/net/core/wwmem_default
/proc/sys/net/core/rmmem_max
/proc/sys/net/core/wmmem_max

队列的长度最好是每一个nfsd有8k的大小。这样,server端就可以对client的请求作排队处理。如果要永久更改此值
#vi /etc/sysctl.conf
net.core.rmmem_default=数目
net.core.wmmem_default=数目
net.core.rmmem_max=数目
net.core.wmmem_max=数目
#service nfs restart