Bei NFS-Datenspeichern in ESXi treten fsync-Latenzen von etwa fünf Sekunden auf, die von bestimmten VMs ausgelöst werden. Ich vermute, dass dies durch VMs mit NCQ / TCQ verursacht werden kann, da dies bei virtuellen IDE-Laufwerken nicht der Fall ist.
Dies kann mit fsync-tester (von Ted Ts'o) und ioping reproduziert werden . Beispiel für die Verwendung eines Grml-Live-Systems mit einer 8-GB-Festplatte:
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 ...]
Das sind 5 Sekunden, keine Millisekunden. Dies führt sogar zu E / A -Latenzen auf einer anderen VM, die auf demselben Host und Datenspeicher ausgeführt wird :
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
Wenn ich die erste VM in den lokalen Speicher verschiebe, sieht das ganz normal aus:
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 ...]
Dinge, die ich ausprobiert habe, die keinen Unterschied machten:
- Mehrere ESXi-Builds getestet: 381591, 348481, 260247
- Getestet auf unterschiedlicher Hardware, verschiedenen Intel- und AMD-Boxen
- Getestet mit verschiedenen NFS-Servern zeigen alle dasselbe Verhalten:
- OpenIndiana b147 (ZFS-Synchronisierung immer oder deaktiviert: kein Unterschied)
- OpenIndiana b148 (ZFS-Synchronisierung immer oder deaktiviert: kein Unterschied)
- Linux 2.6.32 (synchron oder asynchron: kein Unterschied)
- Es spielt keine Rolle, ob sich der NFS-Server auf demselben Computer (als virtuelle Speicher-Appliance) oder auf einem anderen Host befindet
Gastbetriebssystem getestet, zeigt Probleme:
- Windows 7 64 Bit (bei Verwendung von CrystalDiskMark treten Latenzspitzen hauptsächlich während der Vorbereitungsphase auf)
- Linux 2.6.32 (fsync-tester + ioping)
- Linux 2.6.38 (fsync-tester + ioping)
Ich konnte dieses Problem auf Linux 2.6.18-VMs nicht reproduzieren.
Eine andere Problemumgehung besteht darin, virtuelle IDE-Festplatten (im Vergleich zu SCSI / SAS) zu verwenden. Dies schränkt jedoch die Leistung und die Anzahl der Laufwerke pro VM ein.
Update 30.06.2011:
Die Latenzspitzen scheinen häufiger aufzutreten, wenn die Anwendung vor fsync in mehrere kleine Blöcke schreibt. Zum Beispiel macht fsync-tester das (strace output):
pwrite(3, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"..., 1048576, 0) = 1048576
fsync(3) = 0
Ioping tut dies während der Vorbereitung der Datei:
[lots of pwrites]
pwrite(3, "********************************"..., 4096, 1036288) = 4096
pwrite(3, "********************************"..., 4096, 1040384) = 4096
pwrite(3, "********************************"..., 4096, 1044480) = 4096
fsync(3) = 0
Die Einrichtungsphase von ioping hängt fast immer, während fsync-tester manchmal gut funktioniert. Kann jemand fsync-tester aktualisieren, um mehrere kleine Blöcke zu schreiben? Meine C-Fähigkeiten sind zum Kotzen;)
Update 02.07.2011:
Dieses Problem tritt bei iSCSI nicht auf. Ich habe dies mit dem OpenIndiana COMSTAR iSCSI-Server versucht. ISCSI bietet jedoch keinen einfachen Zugriff auf die VMDK-Dateien, sodass Sie sie mit Snapshots und Rsync zwischen Hosts verschieben können.
Update 06.07.2011:
Dies ist Teil einer Wireshark-Erfassung, die von einer dritten VM auf demselben vSwitch erfasst wird. Dies geschieht alles auf demselben Host, ohne dass ein physisches Netzwerk beteiligt ist.
Ich habe gegen 20 Uhr angefangen zu jopen. Es wurden keine Pakete gesendet, bis die fünf Sekunden Verzögerung vorbei waren:
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
2. Update 06.07.2011:
Die TCP-Fenstergröße scheint einen gewissen Einfluss zu haben. Ich konnte dieses Problem mit FreeNAS (basierend auf FreeBSD) als NFS-Server nicht reproduzieren. Die Wireshark-Erfassungen zeigten in regelmäßigen Abständen TCP-Fensteraktualisierungen auf 29127 Bytes. Ich habe sie nicht mit OpenIndiana gesehen, das standardmäßig größere Fenster verwendet.
Ich kann dieses Problem nicht mehr reproduzieren, wenn ich die folgenden Optionen in OpenIndiana festgelegt und den NFS-Server neu gestartet habe:
ndd -set /dev/tcp tcp_recv_hiwat 8192 # default is 128000
ndd -set /dev/tcp tcp_max_buf 1048575 # default is 1048576
Dies beeinträchtigt jedoch die Leistung: Das Schreiben von / dev / zero in eine Datei mit dd_rescue geht von 170 MB / s auf 80 MB / s über.
Update 2011-07-07:
Ich habe dieses tcpdump-Capture hochgeladen (kann mit wireshark analysiert werden). In diesem Fall ist 192.168.250.2 der NFS-Server (OpenIndiana b148) und 192.168.250.10 der ESXi-Host.
Dinge, die ich während dieser Aufnahme getestet habe:
Gestartet mit "Ioping -w 5 -i 0,2". zum Zeitpunkt 30 hängen 5 Sekunden im Setup, abgeschlossen zum Zeitpunkt 40.
Gestartet mit "Ioping -w 5 -i 0,2". zum Zeitpunkt 60 hängen 5 Sekunden im Setup, abgeschlossen zum Zeitpunkt 70.
Startete "fsync-tester" zum Zeitpunkt 90 mit der folgenden Ausgabe und stoppte zum Zeitpunkt 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
2. Aktualisierung 07.07.2011:
Getestet eine andere NFS-Server-VM, diesmal NexentaStor 3.0.5 Community Edition: Zeigt die gleichen Probleme.
Update 2011-07-31:
Ich kann dieses Problem auch auf dem neuen ESXi-Build 4.1.0.433742 reproduzieren.