NFS 客户端的读写速度不平衡

Ban*_*jer 5 networking linux nfs netapp

我有一台 NetApp 作为我的 nfs 服务器,两台 Linux 服务器作为 nfs 客户端。问题是,这两个服务器的更新也极为不同的读取和写入速度,只要它做读取,同时写入到NFS服务器。另外,这个新服务器的读取和写入看起来很棒。旧服务器没有这个问题。

老宿主:鲤鱼

Sun Fire x4150,带 8 核,32 GB RAM

SLES 9 SP4

网络驱动:e1000

me@carp:~> uname -a
Linux carp 2.6.5-7.308-smp #1 SMP Mon Dec 10 11:36:40 UTC 2007 x86_64 x86_64 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)

新主持人:小辣椒

HP ProLiant Dl360P Gen8 带 8 核,64 GB RAM

CentOS 6.3

网络驱动程序:tg3

me@pepper:~> uname -a
Linux pepper 2.6.32-279.el6.x86_64 #1 SMP Fri Jun 22 12:19:21 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)

我将跳到一些说明读/写测试的图表。这是胡椒及其不平衡的读/写:

辣椒产量

这是鲤鱼,看起来不错:

鲤鱼吞吐量

测试

这是我正在运行的读/写测试。我分别运行了它们,它们在胡椒上看起来很棒,但是当一起运行时(使用&),写入性能保持稳定,而读取性能却受到很大影响。测试文件是 RAM 大小的两倍(胡椒使用 128 GB,鲤鱼使用 64 GB)。

# write
time dd if=/dev/zero of=/mnt/peppershare/testfile bs=65536 count=2100000 &
# read 
time dd if=/mnt/peppershare/testfile2 of=/dev/null bs=65536 &
Run Code Online (Sandbox Code Playgroud)

NFS 服务器主机名是 nfsc。Linux 客户端在与其他任何事物分开的子网上(即与主 IP 不同的子网)上有一个专用 NIC。每个 Linux 客户端都将一个 nfs 共享从服务​​器 nfsc 挂载到 /mnt/hostnameshare。

nfsiostat

这是胡椒的 simul r/w 测试期间的 1 分钟样本:

me@pepper:~> nfsiostat 60

nfsc:/vol/pg003 mounted on /mnt/peppershare:

   op/s         rpc bklog
1742.37            0.00
read:             ops/s            kB/s           kB/op         retrans         avg RTT (ms)    avg exe (ms)
                 49.750         3196.632         64.254        0 (0.0%)           9.304          26.406
write:            ops/s            kB/s           kB/op         retrans         avg RTT (ms)    avg exe (ms)
                1642.933        105628.395       64.293        0 (0.0%)           3.189         86559.380
Run Code Online (Sandbox Code Playgroud)

我的旧主机鲤鱼上还没有 nfsiostat,但正在处理它。

/过程/挂载

me@pepper:~> cat /proc/mounts | grep peppershare 
nfsc:/vol/pg003 /mnt/peppershare nfs rw,noatime,nodiratime,vers=3,rsize=65536,wsize=65536,namlen=255,acregmin=0,acregmax=0,acdirmin=0,acdirmax=0,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=172.x.x.x,mountvers=3,mountport=4046,mountproto=tcp,local_lock=none,addr=172.x.x.x 0 0

me@carp:~> cat /proc/mounts | grep carpshare 
nfsc:/vol/pg008 /mnt/carpshare nfs rw,v3,rsize=32768,wsize=32768,acregmin=0,acregmax=0,acdirmin=0,acdirmax=0,timeo=60000,retrans=3,hard,tcp,lock,addr=nfsc 0 0
Run Code Online (Sandbox Code Playgroud)

网卡设置

me@pepper:~> sudo ethtool eth3
Settings for eth3:
        Supported ports: [ TP ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Half 1000baseT/Full
        Supports auto-negotiation: Yes
        Advertised link modes:  10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Half 1000baseT/Full
        Advertised pause frame use: Symmetric
        Advertised auto-negotiation: Yes
        Speed: 1000Mb/s
        Duplex: Full
        Port: Twisted Pair
        PHYAD: 4
        Transceiver: internal
        Auto-negotiation: on
        MDI-X: off
        Supports Wake-on: g
        Wake-on: g
        Current message level: 0x000000ff (255)
        Link detected: yes

me@carp:~> sudo ethtool eth1
Settings for eth1:
        Supported ports: [ TP ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Supports auto-negotiation: Yes
        Advertised link modes:  10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Advertised auto-negotiation: Yes
        Speed: 1000Mb/s
        Duplex: Full
        Port: Twisted Pair
        PHYAD: 1
        Transceiver: internal
        Auto-negotiation: on
        Supports Wake-on: umbg
        Wake-on: g
        Current message level: 0x00000007 (7)
        Link detected: yes
Run Code Online (Sandbox Code Playgroud)

卸载设置:

me@pepper:~> sudo ethtool -k eth3
Offload parameters for eth3:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: on
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off

me@carp:~> # sudo ethtool -k eth1
Offload parameters for eth1:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp segmentation offload: on
Run Code Online (Sandbox Code Playgroud)

这一切都在一个局域网上,在 nfs 客户端和 nfs 服务器之间有一个全双工的千兆交换机。另一方面,我看到胡椒在 CPU 上的 IO 等待比鲤鱼多得多,正如预期的那样,因为我怀疑它在等待 nfs 操作。

我已经用 Wireshark/Ethereal 捕获了数据包,但我在这方面并不强,所以不确定要寻找什么。我在 Wireshark 中没有看到一堆以红色/黑色突出显示的数据包,所以这就是我寻找的全部内容:)。这种糟糕的 nfs 性能已经体现在我们的 Postgres 环境中。

任何进一步的想法或故障排除提示?如果我能提供更多信息,请告诉我。

更新

根据@ewwhite 的评论,我尝试了两种不同的tuned-adm 配置文件,但没有任何变化。

在我的红色标记的右边是另外两个测试。第一座山与throughput-performance,第二座与enterprise-storage

胡椒调整

nfsiostat 60 企业存储配置文件

nfsc:/vol/pg003 mounted on /mnt/peppershare:

   op/s         rpc bklog
1758.65            0.00
read:             ops/s            kB/s           kB/op         retrans         avg RTT (ms)    avg exe (ms)
                 51.750         3325.140         64.254        0 (0.0%)           8.645          24.816
write:            ops/s            kB/s           kB/op         retrans         avg RTT (ms)    avg exe (ms)
                1655.183        106416.517       64.293        0 (0.0%)           3.141         159500.441
Run Code Online (Sandbox Code Playgroud)

更新 2

sysctl -a 表示胡椒

Ban*_*jer 6

noac在 fstab 中添加nfs 挂载选项是灵丹妙药。总吞吐量没有改变,仍然在 100 MB/s 左右,但我的读写现在更加平衡了,我不得不想象这对 Postgres 和其他应用程序来说是个好兆头。

在此处输入图片说明

您可以看到我标记了测试时使用的各种“块”大小,即 rsize/wsize 缓冲区大小安装选项。令人惊讶的是,我发现 8k 大小在 dd 测试中具有最佳吞吐量。

这些是我现在使用的 nfs 挂载选项,每个/proc/mounts

nfsc:/vol/pg003 /mnt/peppershare nfs rw,sync,noatime,nodiratime,vers=3,rsize=8192,wsize=8192,namlen=255,acregmin=0,acregmax=0,acdirmin=0,acdirmax=0,hard,noac,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=172.x.x.x,mountvers=3,mountport=4046,mountproto=tcp,local_lock=none,addr=172.x.x.x 0 0
Run Code Online (Sandbox Code Playgroud)

仅供参考,noac选项 man 条目:

交流/无交流

选择客户端是否可以缓存文件属性。如果两个选项都没有指定(或者如果指定了 ac),客户端缓存文件属性。

为了提高性能,NFS 客户端缓存文件属性。每隔几秒钟,NFS 客户端就会检查每个文件属性的服务器版本以进行更新。在这些小的时间间隔内发生在服务器上的更改一直未被检测到,直到客户端再次检查服务器。noac 选项可防止客户端缓存文件属性,以便应用程序可以更快地检测服务器上的文件更改。

除了防止客户端缓存文件属性之外,noac 选项还强制应用程序写入同步,以便对文件的本地更改立即在服务器上可见。这样,其他客户端可以在检查文件属性时快速检测到最近的写入。

使用 noac 选项可在访问相同文件的 NFS 客户端之间提供更大的缓存一致性,但它会显着降低性能。因此,鼓励明智地使用文件锁定。数据和元数据一致性部分包含对这些权衡的详细讨论。

我在网络上阅读了关于属性缓存的不同意见,所以我唯一的想法是它是一个必要的选项,或者与具有较新内核 (>2.6.5) 的 NetApp NFS 服务器和/或 Linux 客户端一起使用。我们在具有 2.6.5 内核的 SLES 9 上没有看到这个问题。

我也读过关于 rsize/wise 的不同意见,通常你采用默认值,目前我的系统是 65536,但 8192 给了我最好的测试结果。我们也会用 postgres 做一些基准测试,所以我们会看到这些不同的缓冲区大小如何。