现网近期一台NAS存储最近在使用的时候,业务反馈有诡异的性能问题。这里记录下关于NAS包的分析。NAS存储对应在LINUX平台上NFS协议,对应在windows平台上使用cifs协议。LINUX主机抓包可以使用的工具为tcpdump、tshark(命令行的wireshark),包分析软件wireshark。

一、客户端抓包

客户端抓包命令如下:

1tcpdump -i eth1 -s0 -w yumnas.cap host 192.168.14.16 -vvv

后面的host为存储端的IP地址。

二、请求类型

nfs-call-reply
nfs-call-reply

按object对象可以分为directory和file等,按请求对象的操作类型可以有:LOOKUP, REMOVE, RENAME, CREATE, READ,etc(具体看字面意思即可明白),对文件或目录的属性进行操作的包又可以分为:ACCESS, GETATTR, SETATTR, etc 。比如我们要读取一个存储上的文件,在不考虑缓存直接命中的情况,读取一个文件可能要经历 LOOKUP(查找文件) —> GETATTR 或 ACCESS (获取属性:权限、属主) —> READ(获取内容) ,每个动作又要经历CALL 与 Reply两个步骤。call 一般是客户端对NAS存储端的请求,reply一般是存储端响应请求或数据给客户端的过程。

nfs-reply
nfs-reply

上图重点看的是Remote Procedure Call (RPC)层与Network File System(NFS)层。上面可能重要需要关注的是fileid这个值,这个是文件或目录的inode值。

nfs-inode
nfs-inode

三、请求数据

找到NFS返回给客户端的READ reply请求,在Network File System层,找到data选项,可以看到下面的十六进制和十进制输出内容,右键可以选择通过export selected packet bytes进行导出。

nfs-data
nfs-data

四、抓取文件路径

下是一个lookup call 方法包的结果:

lookup-call
lookup-call

上面可以看到文件名,但是具体的文件路径是不知道的,要解决这个问题有两种方法。上面已经提到了一种方法,可以通过文件或目录的inode值查找到其对应的位置;另一个方法是在抓包的时候就抓全路径。

tcpdump是不支持抓全路径的,wireshark支持抓全路径。抓包后获取到的文件路径如下:

wireshark-path
wireshark-path

如果在LINUX上使用命令行进行抓包,可以使用如下命令:

1tshark -i eth1 -V -d tcp.port==2049,rpc host 192.168.14.16 -o 'nfs.file_name_snooping:TRUE' -o 'nfs.file_full_name_snooping:TRUE' -o 'nfs.default_fhandle_type:KNFSD_LE' -s 0 -w b.cap

注:这个我在实际测试的时候,发现抓包获取的结果仍然不是全路径,这个可能是跟访问的时候使用的绝对路径或相对路径相关。

参考页面:

NFS_Preferences

How to capture filename (path) for NFSv4 traffic using tshark

另外github上也有一个专门的nfsstrace工具 : https://github.com/epam/nfstrace/ ,有兴趣的也可以研究使用下。