NFS性能排查及调优

  1. 挂载参数。
    1. soft/hard参数

      hard参数:客户端挂载成功后服务器NFS服务失效时,客户端请求服务失败会无限尝试重发,因此访问该文件系统的程序,例如使用cd/ls/df等命令,会出现挂死现象,造成业务失去响应。当服务器重启NFS服务后,客户端等待一段时间返回相应操作结果。

      soft参数:带soft参数挂载时,客户端在尝试有限次数重发后即会返回错误。

      注:不设置此参数时默认使用hard。

    2. timeo/retrans参数

      timeo设置等待重传请求时间,retrans设置对每个请求失败后的重传次数。两个参数都是控制客户端请求超时后的行为的参数。retrans与soft参数一起使用时才有效。

    3. wsize参数

      wsize:未设置时该值由客户端和服务器协商决定。

      注:通常使用默认值,由客户端和服务器协商设置。对于拥塞的低速网络,可以将该值调小,向服务器发送较小的请求包来提高NFS性能。对于高速网络,可以将该值增大,减少向服务器发送的请求包,获得性能的提升。

    4. rsize参数

      rsize:未设置时该值由客户端和服务器协商决定。

      注:通常使用默认值,由客户端和服务器协商设置。对于拥塞的低速网络,可以将该值调小,向服务器发送较短的请求包来提高NFS性能。对于高速网络,可以将该值增大,减少向服务器发送的请求包,获得性能的提升。

    5. ac/noac参数

      ac/noac:通常为了提高性能,NFS客户端缓存文件属性(默认ac),然后每隔一段时间去检查文件属性后更新。在使用ac参数缓存文件属性,还可以带acregmin/acregmax/acdirmin/acdirmax/actimeo四个参数。acregmin/acregmax参数是设置NFS客户端缓存普通文件属性的最短时间和最长时间,单位为秒,超过此时间后对其进行更新。默认最短时间是3秒,最长时间是60秒。

      acdirmin/acdirmax参数是设置NFS客户端缓存目录属性的最短时间和最长时间,单位为秒,超过此时间后对其进行更新。默认最短时间是3秒,最长时间是60秒。

      actimeo参数是将acregmin/acregmax/acdirmin/acdirmax四个参数设置为相同时间,单位为秒。

      注:当服务器上共享文件的属性频繁地被多个客户端改变时,建议使用noac选项,或者使用ac并配合使用较小的acregmin/acregmax/acdirmin/acdirmax设置,这样就能获得较好的属性一致性。当服务器上共享文件的属性不会被频繁改变时,例如文件共享为只读,或者网络性能较好,建议使用默认的ac选项,然后根据实际的网络状况来调整acregmin/acregmax/acdirmin/acdirmax设置。

    6. sharecache/nosharecache参数

      sharecache/nosharecache:同一客户端使用不同的本地目录挂载同一个NFS共享,挂载时使用sharecache参数会让客户端共享NFS数据缓存。

      使用nosharecache参数一份文件有多个缓存拷贝会有数据不一致的问题。

      注:该参数用于客户端多次挂载同一共享目录的情况,建议使用默认的sharecache选项。

    7. lookupcache=mode参数

      lookupcache=mode:mode有all/none/pos三种缓存结果的方式。all缓存的是文件存在的结果和文件不存在的结果,因此当第二次查询同一个文件时,由于客户端已缓存了结果,所有不会再次发送LOOKUP命令字。

      该选项能快速检测其它客户端创建或删除的文件,但对会影响服务器性能。

      注:LOOKUP命令字的作用是将文件名转换文件句柄。对于多个客户端经常创建或删除文件的情况,建议使用none,其它情况选用all或者pos。

    8. cto/nocto参数

      cto/nocto:Linux对“关闭打开”(close-to-open)缓存一致的特性的实现,是对一个文件关闭时的GETATTR查询结果和下次打开该文件时GETATTR查询结果进行对比完成的(http://nfs.sourceforge.net/)。如果查询结果一样,则说明客户端缓存数据仍有效,否则缓存应该被清除。

      使用默认参数cto挂载读取同一文件,在第二次读取文件之前,客户端发送GETATTR获取属性与缓存的结果对比,发现文件未改变,因此客户端第二次没有发送READ,直接从自己的缓存中读出文件内容。若第二次读取文件之前,在服务端改变文件内容,客户端发送GETATTR取回结果与缓存的结果对比,检测到这个变化,因此客户端第二次会发送READ,从服务器上重新读取文件内容。cto保持数据一致性。

      使用参数nocto挂载读取同一文件,在第二次读取文件之前,客户端不会发送GETATTR,直接从自己的缓存中读出文件内容。若第二次读取文件之前,在服务端改变文件内容,客户端不会检测到这个变化,因此客户端第二次读取的是过时数据。等待一段时间后,客户端向服务器发送了READ重新读取文件,获得新的文件内容。

      注:对于文件内容改变很少的情况,如服务器提供只读共享权限(文件系统以RO权限导出)给客户使用,建议使用nocto选项,这样可以提高性能。对于文件内容经常改变,客户端对文件缓存一致性要求较高,建议使用cto参数。

    9. tcp/udp参数

      tcp/udp:使用tcp协议传输请求稳定性较好,保证了传输的正确性和可靠性;使用udp协议传输请求的传输速度较快,满足客户端的响应性能。

      注:在不稳定的复杂网络环境中建议使用tcp参数,在稳定的网络下可以使用udp参数。NFSv3/NFSv4支持tcp/udp,NFSv2只支持udp。

  2. NFS性能调优选项。
    1. 协议选项

      最大传输块

      用于设置NFS协议报文块的大小,也就是协议客户端一个报文允许携带的最大载荷,NFS默认1M(1048576),最大可设置为1M。

      可通过命令echo 1048576 > /proc/fs/nfsd/max_block_size进行配置(重启失效)。

      通信线程数

      设置协议通信线程数。通信线程处理能力不够时增大该值。

      可通过命令echo 32 > /proc/fs/nfsd/threads进行配置。

      通信线程数是否不够的问题,可通过netstat工具查看nfs连接上收发包缓冲区的积压情况大概查看一下,重点关注TCP的情况(默认使用TCP),2049为nfs业务端口。

      业务线程数

      设置协议业务线程数。业务线程处理能力不够时增大该值。

      可通过命令echo 32 > /proc/fs/nfsd/pool_threads进行配置。

    2. TCP/IP选项

      Linux

      net.ipv4.tcp_rmem = 10000000 20000000 40000000

      TCP接收缓冲区的大小,实际上是TCP接收窗口的缺省值。在10GE网卡上建议调整为10MB 20MB 40MB。

      echo 10000000 20000000 40000000 > /proc/sys/net/ipv4/tcp_rmem
      net.ipv4.tcp_wmem = 10000000 20000000 40000000
      echo 10000000 20000000 40000000 > /proc/sys/net/ipv4/tcp_wmem

      TCP发送缓冲区的大小。在10GE网卡上建议调整为10MB 20MB 40MB。

      net.ipv4.tcp_mem = 400000  800000  1600000

      TCP协议栈能够使用的内存页面数量,每个页面4KB。建议调整为上述值,即:400MB 800MB 1.6GB。

      net.ipv4.tcp_window_scaling = 1

      TCP窗口缩放因数选项,开启该选项后才可以支持大于64K的TCP窗口。

      注:tcp_rmem和tcp_wmem两个值只需要在客户端上修改。

    3. 网卡选项

      Linux

      1. 1支持巨帧
        ip link set all xxx mtu 9000
        ifconfig xxx mtu 9000
      2. 开启流控
        ethtool –A xxx rx on
        ethtool –A xxx tx on
      3. 中断聚合
        ethtool –C xxx rx-usecs 32
    4. 系统选项

      Linux

      1. RPC并发请求数
        echo 128 > /proc/sys/sunrpc/tcp_slot_table_entries

        注:修改完该值需要umount后重新mount才会生效。

  3. 性能问题分析定位。
    1. 时延分析

      NFS应用的分层图如下,左边表示客户端侧,右边表示服务端侧。

      其中标有序号的①—⑧都有对应的时延统计信息,获取相邻两点之间的时延,就能准确定位是哪一层耗时了。

      应用层统计

      应用时延统计(如vdbench)会有相应的时延,速率,ops等信息输出,在此不再赘述。

      客户端NFS/SUNRPC统计

      1. nfsiostat

        输出的是实时统计,但只能统计read和write命令字。

        - op/s
        This is the number of operations per second.
        - rpc bklog
        This is the length of the backlog queue.
        - kB/s
        This is the number of kB written/read per second.
        - kB/op
        This is the number of kB written/read per each operation.
        - retrans
        This is the number of retransmissions.
        - avg RTT (ms)
        This is the duration from the time that client's kernel sends the RPC request until the time it receives the reply.
        - avg exe (ms)
        This is the duration from the time that NFS client does the RPC request to its kernel until the RPC request is completed, this includes the RTT time above.
      2. mountstats

        输出的为累积统计值,可以统计所有命令字。输出信息有详细说明,需关注命令字统计对应的的backlog wait、RTT和total execute time。

      3. /proc/1/mountstats

        是nfsiostat、mountstats命令的源数据。主要关注xprt和命令对应的统计。

        1. xprt统计
          xprt:   tcp 734 0 1 0 0 2173669 2173156 0 904604335 0 10 1165672 2493580
          l  1. srcport:         Ephemeral port
          l  2. bind_count:      How many rpcbind operations
          l  3. connect_count:   How many TCP connects
          l  4. connect_time:    How long connects have taken
          l  5. idle_time:       How long transport has been idle
          l  6. rpcsends:        How many socket sends
          l  7. rpcrecvs:        How many socket receives
          l  8. badxids:         How many unmatchable XIDs have been received
          l  9. req_u:      Average requests on the wire (slot table utilization)
          l  10. bklog_u:        backlog queue utilization (average length of baklog queue)
          l  11. max_slots:      max rpc_slots used
          l  12. sending_u:      send q utilization
          l  13. pending_u:      pend q utilization

          第10项/第6项:表示平均每个请求排队个数。

        2. per-op statistics
          READ: 276305 276305 0 54882824 197516342140 16993798 857262 18130986
          l  1.operations: How many requests we've done for this operation.
          l  2.transmissions: How many times we've actually transmitted a RPC request for this operation. As you might have gathered from the last entry, this can exceed the operation count due to timeouts and retries.
          l  3.major timeouts: How many times a request has had a major timeout. Major timeouts produce 'nfs: server X not responding, still trying' messages. You can have timeouts and retries without having major timeouts (and my example lines do).
          l  4.bytes sent: This includes not just the RPC payload but also the RPC headers and so on. It closely matches the on-the-wire size.
          l  5.bytes received: As with bytes sent, this is the full size.
          l  6.cumulative queue time: How long (in milliseconds) all requests spent queued for transmission before they were sent.
          l  7.cumulative response time: How long (in milliseconds) it took to get a reply back after the request was transmitted. The kernel comments call this the RPC RTT.
          l  8.cumulative total request time: How long (in milliseconds) all requests took from when they were initially queued to when they were completely handled. The kernel calls this the RPC execution time.

          第8项/第1项:表示总的平均处理时延。

          第7项/第1项:表示客户端发送请求到收到响应的平均时延

          第6项/第1项:表示客户端排队的平均时延。

        客户端ETH统计

        使用tcpdump捕获数据包,然后使用wireshark工具进行分析。

        1. wireshark选择Statistics——Service Response Time——ONC-RPC

        2. Program中选择NFS,Version选择3(即分析NFSv3),然后点击Create Stat按钮

        3. 统计数据,最后一列是平均时延,单位秒

    2. 并发分析

      Linux NFS 客户端对于同时发起的NFS请求数量进行了控制,若该参数配置较小,会降低 IO 性能。/proc/sys/sunrpc/tcp_slot_table_entries,Ubuntu18.04上默认是2。

      可以通过命令echo 128 > /proc/sys/sunrpc/tcp_slot_table_entries进行配置。

      注:配置完成后需要重新挂载nfs共享。

    3. 网络分析

      netstat

      1. netstat -nap

        主要关注第二列和第三列,分别表示接收队列和发送队列,单位字节。如果该大小长期等于TCP缓冲区大小,则底层可能出问题了,需要定位系统或者网卡模块的问题。

      2. netstat -s

        重点关注Abort、Drop字段的相关统计,如果下业务过程中,这些值不断增加,则需要定位系统问题。

挂载soft/hard参数

表1 参数说明

参数

说明

hard

客户端挂载成功后服务器NFS服务失效时,客户端请求服务失败会无限尝试重发,因此访问该文件系统的程序,例如使用cdlsdf等命令,会出现挂死现象,造成业务失去响应。当服务器重启NFS服务后,客户端等待一段时间返回相应操作结果。

soft

带soft参数挂载时,客户端在尝试有限次数重发后即会返回错误。