解决ESXi NFS数据存储上的延迟峰值问题

在某些虚拟机触发的情况下,ESXi中的NFS数据存储上遇到大约五秒的 fsync延迟。 我怀疑这可能是由使用NCQ / TCQ的虚拟机引起的,因为虚拟IDE驱动器不会发生这种情况。

这可以使用fsync-tester (Ted Ts'o)和Ioping来复制 。 例如,使用带有8GB磁盘的Grml Live系统:

Linux 2.6.33-grml64: root@dynip211 /mnt/sda # ./fsync-tester fsync time: 5.0391 fsync time: 5.0438 fsync time: 5.0300 fsync time: 0.0231 fsync time: 0.0243 fsync time: 5.0382 fsync time: 5.0400 [... goes on like this ...] 

那是5秒,而不是毫秒。 这甚至在运行在同一主机和数据存储上的不同虚拟机上创buildIO延迟

 root@grml /mnt/sda/ioping-0.5 # ./ioping -i 0.3 -p 20 . 4096 bytes from . (reiserfs /dev/sda): request=1 time=7.2 ms 4096 bytes from . (reiserfs /dev/sda): request=2 time=0.9 ms 4096 bytes from . (reiserfs /dev/sda): request=3 time=0.9 ms 4096 bytes from . (reiserfs /dev/sda): request=4 time=0.9 ms 4096 bytes from . (reiserfs /dev/sda): request=5 time=4809.0 ms 4096 bytes from . (reiserfs /dev/sda): request=6 time=1.0 ms 4096 bytes from . (reiserfs /dev/sda): request=7 time=1.2 ms 4096 bytes from . (reiserfs /dev/sda): request=8 time=1.1 ms 4096 bytes from . (reiserfs /dev/sda): request=9 time=1.3 ms 4096 bytes from . (reiserfs /dev/sda): request=10 time=1.2 ms 4096 bytes from . (reiserfs /dev/sda): request=11 time=1.0 ms 4096 bytes from . (reiserfs /dev/sda): request=12 time=4950.0 ms 

当我将第一台虚拟机移动到本地存储时,看起来非常正常:

 root@dynip211 /mnt/sda # ./fsync-tester fsync time: 0.0191 fsync time: 0.0201 fsync time: 0.0203 fsync time: 0.0206 fsync time: 0.0192 fsync time: 0.0231 fsync time: 0.0201 [... tried that for one hour: no spike ...] 

我试过的东西没有什么区别:

  • testing了几个ESXi版本:381591,348481,260247
  • testing不同的硬件,不同的英特尔和AMD的盒子
  • testing了不同的NFS服务器,都显示相同的行为:
    • OpenIndiana b147(ZFS同步总是或禁用:没有区别)
    • OpenIndiana b148(ZFS同步总是或禁用:没有区别)
    • Linux 2.6.32(同步或asynchronous:没有区别)
    • 如果NFS服务器位于同一台计算机(作为虚拟存储设备)或不同的主机上,则不会有任何区别

来宾操作系统testing,显示问题:

  • Windows 7 64位(使用CrystalDiskMark,主要是在准备阶段发生延迟尖峰)
  • Linux 2.6.32(fsync-tester + ioping)
  • Linux 2.6.38(fsync-tester + ioping)

我无法在Linux 2.6.18 VM上重现这个问题。

另一个解决方法是使用虚拟IDE磁盘(vs SCSI / SAS),但这会限制性能和每个虚拟机的驱动器数量。

更新2011-06-30:

如果应用程序在fsync之前的多个小块中写入,则延迟尖峰似乎会更频繁地发生。 例如fsync-tester这样做(strace输出):

 pwrite(3, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"..., 1048576, 0) = 1048576 fsync(3) = 0 

在编写文件时,Ioping会这样做:

 [lots of pwrites] pwrite(3, "********************************"..., 4096, 1036288) = 4096 pwrite(3, "********************************"..., 4096, 1040384) = 4096 pwrite(3, "********************************"..., 4096, 1044480) = 4096 fsync(3) = 0 

ioping的设置阶段几乎总是挂起,而fsync-tester有时工作正常。 是否有人能够更新fsync-tester来编写多个小块? 我的C技能吸吮;)

更新2011-07-02:

iSCSI不会发生此问题。 我用OpenIndiana COMSTAR iSCSI服务器试了一下。 但iSCSI不能让您轻松访问VMDK文件,因此您可以在具有快照和rsync的主机之间移动它们。

更新2011-07-06:

这是Wireshark捕获的一部分,由同一个vSwitch上的第三个VM捕获。 这一切都发生在同一台主机上,没有涉及物理networking。

我已经开始在时间20左右。没有数据包发送,直到五秒延迟结束:

 No. Time Source Destination Protocol Info 1082 16.164096 192.168.250.10 192.168.250.20 NFS V3 WRITE Call (Reply In 1085), FH:0x3eb56466 Offset:0 Len:84 FILE_SYNC 1083 16.164112 192.168.250.10 192.168.250.20 NFS V3 WRITE Call (Reply In 1086), FH:0x3eb56f66 Offset:0 Len:84 FILE_SYNC 1084 16.166060 192.168.250.20 192.168.250.10 TCP nfs > iclcnet-locate [ACK] Seq=445 Ack=1057 Win=32806 Len=0 TSV=432016 TSER=769110 1085 16.167678 192.168.250.20 192.168.250.10 NFS V3 WRITE Reply (Call In 1082) Len:84 FILE_SYNC 1086 16.168280 192.168.250.20 192.168.250.10 NFS V3 WRITE Reply (Call In 1083) Len:84 FILE_SYNC 1087 16.168417 192.168.250.10 192.168.250.20 TCP iclcnet-locate > nfs [ACK] Seq=1057 Ack=773 Win=4163 Len=0 TSV=769110 TSER=432016 1088 23.163028 192.168.250.10 192.168.250.20 NFS V3 GETATTR Call (Reply In 1089), FH:0x0bb04963 1089 23.164541 192.168.250.20 192.168.250.10 NFS V3 GETATTR Reply (Call In 1088) Directory mode:0777 uid:0 gid:0 1090 23.274252 192.168.250.10 192.168.250.20 TCP iclcnet-locate > nfs [ACK] Seq=1185 Ack=889 Win=4163 Len=0 TSV=769821 TSER=432716 1091 24.924188 192.168.250.10 192.168.250.20 RPC Continuation 1092 24.924210 192.168.250.10 192.168.250.20 RPC Continuation 1093 24.924216 192.168.250.10 192.168.250.20 RPC Continuation 1094 24.924225 192.168.250.10 192.168.250.20 RPC Continuation 1095 24.924555 192.168.250.20 192.168.250.10 TCP nfs > iclcnet_svinfo [ACK] Seq=6893 Ack=1118613 Win=32625 Len=0 TSV=432892 TSER=769986 1096 24.924626 192.168.250.10 192.168.250.20 RPC Continuation 1097 24.924635 192.168.250.10 192.168.250.20 RPC Continuation 1098 24.924643 192.168.250.10 192.168.250.20 RPC Continuation 1099 24.924649 192.168.250.10 192.168.250.20 RPC Continuation 1100 24.924653 192.168.250.10 192.168.250.20 RPC Continuation 

2011年2月6日第二次更新:

似乎有一些TCP窗口大小的影响。 我无法使用FreeNAS(基于FreeBSD)作为NFS服务器来重现这个问题。 wireshark捕获显示TCP窗口定期更新到29127字节。 我没有看到OpenIndiana,默认使用较大的窗口大小。

我不能再重现这个问题,如果我在OpenIndiana中设置以下选项并重新启动NFS服务器:

 ndd -set /dev/tcp tcp_recv_hiwat 8192 # default is 128000 ndd -set /dev/tcp tcp_max_buf 1048575 # default is 1048576 

但是这会导致性能下降:使用dd_rescue从/ dev / zero写入文件的速度从170MB / s到80MB / s。

2011-07-07更新:

我已经上传了这个tcpdump捕获 (可以用wireshark进行分析)。 在这种情况下,192.168.250.2是NFS服务器(OpenIndiana b148),而192.168.250.10是ESXi主机。

我在testing过程中testing过的东西:

开始“I -W 5 -i 0.2”。 在时间30,5秒挂在设置,在时间40完成。

开始“I -W 5 -i 0.2”。 在时间60,5秒钟挂在设置,在时间70完成。

在时间90开始“fsync-tester”,输出如下,在时间120停止:

 fsync time: 0.0248 fsync time: 5.0197 fsync time: 5.0287 fsync time: 5.0242 fsync time: 5.0225 fsync time: 0.0209 

2011-07-07第二次更新:

testing另一个NFS服务器虚拟机,这次NexentaStor 3.0.5社区版:显示相同的问题。

2011-07-31更新:

我也可以在新的ESXi版本4.1.0.433742上重现这个问题。

    这个问题似乎在ESXi 5中得到解决。我已经成功testing了版本469512。

    谢谢,nfsstat看起来不错。 我已经回顾了捕获。 还没有find任何结论性的,但确实发现了一些有趣的事情。 我过滤了tcp.time_delta> 5.我在每个延迟实例中发现的是RPC调用的确切开始。 并非所有新的RPC调用都很慢,但是所有的减速都发生在RPC调用的确切开始处。 另外,从捕获看来,192.168.250.10包含了所有的延迟。 192.168.250.2立即响应所有请求。

    发现:

    • 延迟总是出现在RPC调用的第一个数据包中
    • NFS命令types与延迟实例不相关
    • 碎片=只延迟第一个数据包

    一个大的写入呼叫可以分解成300个单独的TCP数据包,只有第一个被延迟,但其余的都通过。 从来没有延迟发生在中间。 我不确定窗口大小如何激烈地影响连接的开始

    接下来的步骤:我开始调整像NFSSVC_MAXBLKSIZE向下的NFS选项,而不是TCP窗口。 另外,我注意到2.6.18工作,而2.6.38不工作。 我知道在这段时间内VMXnet3驱动程序已经添加了支持。 你在主机上使用什么网卡驱动程序? TCP卸载是/否? 95秒左右,一个NFS Write调用就有超过500个TCP数据包。 无论是负责TCP和分解大PDU可能是什么阻塞。

    使用ESXi4.1U1和CentOS虚拟机,我看起来像是同样的问题。 主机是Dell R610,存储是EMC2 Isilon群集。

    你有没有机会使用VLANS? 我发现使用VMkernel端口上的VLAN进行存储会导致VMHost上所有存储stream量的“4000-5000ms”挂起。 但是,如果我将VMkernel端口从VLAN中移出,以便收到未加标签的数据包,则不会看到问题。

    下面的简单设置将导致我的networking上的问题:

    1)在服务器或工作站上安装ESXi 4.1U1(我尝试时都出现这个问题)

    2)在VLAN上添加一个VMkernel端口。

    3)添加一个NFS数据存储(我的是在同一个VLAN,即Isilon接收标记的数据包)

    4)安装2个CentOS 5.5 VM,一个用Ioping。

    5)启动虚拟机进入单用户模式(即没有networking,最低限度的服务)

    6)在一台机器上运行Ioping,以便写入虚拟磁盘

    7)在另一台机器上运行dd或者其他机器,将100MB的数据写入/ tmp或类似的文件

    我经常看到两个虚拟机冻结4-5秒。

    真的有兴趣看看有没有人看过类似的东西。

    两星期前我们也遇到了同样的问题。 ESX41 U1和Netapp FAS3170 + NFS数据存储。 RHEL5虚拟机挂起2到4秒钟,我们看到Virtual Center性能控制台的高峰。

    我要求networking人员检查configuration,问题出在Cisco交换机上。我们有两个以太网链路,configuration在Netapp端的Etherchannel上,而不是在Cisco端。 他在思科上创build了一个静态Ethechannel,现在工作正常。 要识别此类问题,请closures除文件pipe理器和交换机之间的所有端口。 只留下一个端口,看看事情进展如何。

    我们做的第二件事就是删除switchcj和filer上的stream量控制,因为我们怀疑它发送暂停帧。

    你的DNS看起来如何? 你的/etc/resolv.conf是否正确? 默认的超时时间是5秒。

    man resolv.conf

     timeout:n sets the amount of time the resolver will wait for a response from a remote name server before retrying the query via a different name server. Measured in seconds, the default is RES_TIMEOUT (currently 5, see <resolv.h>). 

    尝试将timeout:3添加到/etc/resolv.conf ,然后再次运行fsynctesting。

    在这里抓住吸pipe,但是你在这些服务器上使用什么网卡? 堆栈溢出系统pipe理员在使用Broadcom网卡时出现了奇怪的networking问题,这些网卡在切换到英特尔网卡时就消失了: http : //blog.serverfault.com/post/broadcom-die-mutha/

    这是另一个猜测…是否在EXS主机上启用了IPv6? 如果是的话,试试把它关掉? 根据我的经验,如果您的整个networking没有正确configuration为IPv6(即RADV,DHCP6,DNS,反向DNS),这可能是一些服务的问题。 另外,确保它在NFS服务器上是closures的。