Estoy experimentando latencias fsync de alrededor de cinco segundos en almacenes de datos NFS en ESXi, activadas por ciertas máquinas virtuales. Sospecho que esto podría ser causado por máquinas virtuales que usan NCQ / TCQ, ya que esto no sucede con las unidades IDE virtuales.
Esto se puede reproducir usando fsync-tester (por Ted Ts'o) y ioping . Por ejemplo, usando un sistema en vivo Grml con un disco de 8GB:
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 ...]
Eso es 5 segundos, no milisegundos. Esto incluso está creando latencias de E / S en una VM diferente que se ejecuta en el mismo host y almacén de datos :
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
Cuando muevo la primera VM al almacenamiento local, parece perfectamente normal:
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 ...]
Cosas que he probado que no hicieron ninguna diferencia:
- Probado varias versiones de ESXi: 381591, 348481, 260247
- Probado en diferentes hardware, diferentes cajas Intel y AMD
- Probado con diferentes servidores NFS, todos muestran el mismo comportamiento:
- OpenIndiana b147 (sincronización ZFS siempre o deshabilitada: no hay diferencia)
- OpenIndiana b148 (sincronización ZFS siempre o deshabilitada: no hay diferencia)
- Linux 2.6.32 (sincronización o asíncrono: no hay diferencia)
- No hay diferencia si el servidor NFS está en la misma máquina (como un dispositivo de almacenamiento virtual) o en un host diferente
SO invitado probado, mostrando problemas:
- Windows 7 64 Bit (usando CrystalDiskMark, los picos de latencia ocurren principalmente durante la fase de preparación)
- Linux 2.6.32 (fsync-tester + ioping)
- Linux 2.6.38 (fsync-tester + ioping)
No pude reproducir este problema en máquinas virtuales Linux 2.6.18.
Otra solución es usar discos IDE virtuales (frente a SCSI / SAS), pero eso está limitando el rendimiento y la cantidad de unidades por VM.
Actualización 2011-06-30:
Los picos de latencia parecen ocurrir más a menudo si la aplicación escribe en múltiples bloques pequeños antes de fsync. Por ejemplo, fsync-tester hace esto (salida strace):
pwrite(3, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"..., 1048576, 0) = 1048576
fsync(3) = 0
ioping hace esto mientras prepara el archivo:
[lots of pwrites]
pwrite(3, "********************************"..., 4096, 1036288) = 4096
pwrite(3, "********************************"..., 4096, 1040384) = 4096
pwrite(3, "********************************"..., 4096, 1044480) = 4096
fsync(3) = 0
La fase de configuración de ioping casi siempre se bloquea, mientras que fsync-tester a veces funciona bien. ¿Alguien puede actualizar fsync-tester para escribir varios bloques pequeños? Mis habilidades C apestan;)
Actualización 2011-07-02:
Este problema no ocurre con iSCSI. Intenté esto con el servidor iSCSI de COMSTAR de OpenIndiana. Pero iSCSI no le brinda acceso fácil a los archivos VMDK, por lo que puede moverlos entre hosts con instantáneas y rsync.
Actualización 2011-07-06:
Esto es parte de una captura de Wirehark, capturada por una tercera máquina virtual en el mismo vSwitch. Todo esto sucede en el mismo host, sin ninguna red física involucrada.
Comencé a ioping alrededor del tiempo 20. No se enviaron paquetes hasta que pasaron los cinco segundos de retraso:
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
2da actualización 2011-07-06:
Parece haber cierta influencia de los tamaños de las ventanas TCP. No pude reproducir este problema usando FreeNAS (basado en FreeBSD) como servidor NFS. Las capturas de Wirehark mostraron actualizaciones de la ventana TCP a 29127 bytes a intervalos regulares. No los vi con OpenIndiana, que usa tamaños de ventana más grandes por defecto.
Ya no puedo reproducir este problema si configuro las siguientes opciones en OpenIndiana y reinicio el servidor NFS:
ndd -set /dev/tcp tcp_recv_hiwat 8192 # default is 128000
ndd -set /dev/tcp tcp_max_buf 1048575 # default is 1048576
Pero esto mata el rendimiento: escribir desde / dev / zero en un archivo con dd_rescue va de 170 MB / sa 80 MB / s.
Actualización 2011-07-07:
He subido esta captura tcpdump (puede analizarse con wireshark). En este caso, 192.168.250.2 es el servidor NFS (OpenIndiana b148) y 192.168.250.10 es el host ESXi.
Cosas que probé durante esta captura:
Comenzó "ioping -w 5 -i 0.2". en el momento 30, 5 segundos de configuración de bloqueo, completado en el tiempo 40.
Comenzó "ioping -w 5 -i 0.2". en el momento 60, 5 segundos de configuración de bloqueo, completado en el tiempo 70.
Comenzó "fsync-tester" en el momento 90, con la siguiente salida, se detuvo en el momento 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
2da Actualización 2011-07-07:
Probé otra máquina virtual de servidor NFS, esta vez edición comunitaria NexentaStor 3.0.5: muestra los mismos problemas.
Actualización 2011-07-31:
También puedo reproducir este problema en la nueva compilación ESXi 4.1.0.433742.