Escenario: Tenemos varios clientes de Windows que cargan regularmente archivos grandes (FTP / SVN / HTTP PUT / SCP) a servidores Linux que están a ~ 100-160 ms de distancia. Tenemos un ancho de banda síncrono de 1 Gbit / s en la oficina y los servidores son instancias de AWS o están físicamente alojados en DC de EE. UU.
El informe inicial fue que las cargas a una nueva instancia de servidor fueron mucho más lentas de lo que podrían ser. Esto se confirmó en las pruebas y desde múltiples ubicaciones; los clientes estaban viendo de 2 a 5 Mbit / s estables al host desde sus sistemas Windows.
Estallé iperf -s
en una instancia de AWS y luego de un cliente de Windows en la oficina:
iperf -c 1.2.3.4
[ 5] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 55185
[ 5] 0.0-10.0 sec 6.55 MBytes 5.48 Mbits/sec
iperf -w1M -c 1.2.3.4
[ 4] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 55239
[ 4] 0.0-18.3 sec 196 MBytes 89.6 Mbits/sec
La última cifra puede variar significativamente en las pruebas posteriores, (Vagaries of AWS), pero generalmente está entre 70 y 130Mbit / s, que es más que suficiente para nuestras necesidades. Wiresharking la sesión, puedo ver:
iperf -c
Windows SYN - Ventana 64kb, Escala 1 - Linux SYN, ACK: Ventana 14kb, Escala: 9 (* 512)iperf -c -w1M
Windows SYN - Windows 64kb, Escala 1 - Linux SYN, ACK: Ventana 14kb, Escala: 9
Claramente, el enlace puede mantener este alto rendimiento, pero tengo que establecer explícitamente el tamaño de la ventana para hacer uso de él, lo que la mayoría de las aplicaciones del mundo real no me dejan hacer. Los protocolos de enlace TCP utilizan los mismos puntos de partida en cada caso, pero el forzado escala
Por el contrario, desde un cliente Linux en la misma red, una línea recta iperf -c
(usando el sistema predeterminado 85kb) me da:
[ 5] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 33263
[ 5] 0.0-10.8 sec 142 MBytes 110 Mbits/sec
Sin forzar, se escala como se esperaba. Esto no puede ser algo en los saltos intermedios o en nuestros conmutadores / enrutadores locales y parece afectar a los clientes de Windows 7 y 8 por igual. He leído muchas guías sobre el autoajuste, pero generalmente se trata de deshabilitar la escala por completo para evitar el kit de red doméstica terrible y malo.
¿Alguien puede decirme qué está pasando aquí y darme una manera de arreglarlo? (Preferiblemente, algo que pueda pegar en el registro a través de GPO).
Notas
La instancia de AWS Linux en cuestión tiene las siguientes configuraciones de kernel aplicadas en sysctl.conf
:
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 1048576
net.core.wmem_default = 1048576
net.ipv4.tcp_rmem = 4096 1048576 16777216
net.ipv4.tcp_wmem = 4096 1048576 16777216
He utilizado la dd if=/dev/zero | nc
redirección al /dev/null
servidor para descartar iperf
y eliminar cualquier otro posible cuello de botella, pero los resultados son muy parecidos. Las pruebas con ncftp
(Cygwin, Native Windows, Linux) se escalan de la misma manera que las pruebas iperf anteriores en sus respectivas plataformas.
Editar
He visto otra cosa consistente aquí que podría ser relevante:
Este es el primer segundo de la captura de 1 MB, ampliada. Puede ver el inicio lento en acción a medida que la ventana se amplía y el búfer se hace más grande. Luego está esta pequeña meseta de ~ 0.2s exactamente en el punto en que la prueba de ventana predeterminada iperf se aplana para siempre. Por supuesto, esta escala a alturas mucho más vertiginosas, pero es curioso que haya una pausa en la escala (los valores son 1022bytes * 512 = 523264) antes de hacerlo.
Actualización - 30 de junio.
Seguimiento de las diversas respuestas:
- Habilitación de CTCP: esto no hace ninguna diferencia; La escala de la ventana es idéntica. (Si entiendo esto correctamente, esta configuración aumenta la velocidad a la que se amplía la ventana de congestión en lugar del tamaño máximo que puede alcanzar)
- Habilitación de marcas de tiempo TCP. - No hay cambio aquí tampoco.
- Algoritmo de Nagle: eso tiene sentido y al menos significa que probablemente pueda ignorar esos puntos en particular en el gráfico como cualquier indicación del problema.
- Archivos pcap: archivo Zip disponible aquí: https://www.dropbox.com/s/104qdysmk01lnf6/iperf-pcaps-10s-Win%2BLinux-2014-06-30.zip (Anónimo con bittwiste, se extrae a ~ 150MB ya que hay uno de cada cliente OS para comparar)
Actualización 2 - 30 de junio
O, así que, siguiendo la operación de la sugerencia de Kyle, habilité ctcp y deshabilité la descarga de la chimenea: Parámetros globales TCP
----------------------------------------------
Receive-Side Scaling State : enabled
Chimney Offload State : disabled
NetDMA State : enabled
Direct Cache Acess (DCA) : disabled
Receive Window Auto-Tuning Level : normal
Add-On Congestion Control Provider : ctcp
ECN Capability : disabled
RFC 1323 Timestamps : enabled
Initial RTO : 3000
Non Sack Rtt Resiliency : disabled
Pero lamentablemente, no hay cambio en el rendimiento.
Sin embargo, tengo una pregunta de causa / efecto aquí: los gráficos son del valor RWIN establecido en los ACK del servidor para el cliente. Con los clientes de Windows, ¿estoy en lo cierto al pensar que Linux no está escalando este valor más allá de ese punto bajo porque el CWIN limitado del cliente evita que incluso ese búfer se llene? ¿Podría haber alguna otra razón por la que Linux está limitando artificialmente el RWIN?
Nota: He intentado activar ECN por el placer de hacerlo; pero no hay cambio, ahí.
Actualización 3 - 31 de junio.
Ningún cambio después de deshabilitar la heurística y el autoajuste RWIN. He actualizado los controladores de red Intel a la última versión (12.10.28.0) con un software que expone ajustes de funcionalidad a través de pestañas del administrador de dispositivos. La tarjeta es una NIC integrada en el chipset 82579V (voy a hacer más pruebas de clientes con Realtek u otros proveedores)
Centrándome en la NIC por un momento, he intentado lo siguiente (principalmente descartando culpables poco probables):
- Aumente los búferes de recepción a 2k desde 256 y los búferes de transmisión a 2k desde 512 (Ambos ahora al máximo) - Sin cambios
- Deshabilitó toda la descarga de suma de verificación IP / TCP / UDP. - Ningún cambio.
- Desactivado Descarga de envío grande - Nada.
- Desactivado IPv6, programación de QoS - Nowt.
Actualización 3 - 3 de julio
Intentando eliminar el lado del servidor Linux, inicié una instancia de Server 2012R2 y repetí las pruebas usando iperf
(cygwin binary) y NTttcp .
Con iperf
, tuve que especificar explícitamente -w1m
en ambos lados antes de que la conexión escalara más allá de ~ 5Mbit / s. (Por cierto, podría ser revisado y el BDP de ~ 5 Mbits a 91 ms de latencia es casi exactamente 64 kb. Encuentra el límite ...)
Los binarios ntttcp mostraron ahora tal limitación. Utilizando ntttcpr -m 1,0,1.2.3.5
en el servidor y ntttcp -s -m 1,0,1.2.3.5 -t 10
en el cliente, puedo ver un rendimiento mucho mejor:
Copyright Version 5.28
Network activity progressing...
Thread Time(s) Throughput(KB/s) Avg B / Compl
====== ======= ================ =============
0 9.990 8155.355 65536.000
##### Totals: #####
Bytes(MEG) realtime(s) Avg Frame Size Throughput(MB/s)
================ =========== ============== ================
79.562500 10.001 1442.556 7.955
Throughput(Buffers/s) Cycles/Byte Buffers
===================== =========== =============
127.287 308.256 1273.000
DPCs(count/s) Pkts(num/DPC) Intr(count/s) Pkts(num/intr)
============= ============= =============== ==============
1868.713 0.785 9336.366 0.157
Packets Sent Packets Received Retransmits Errors Avg. CPU %
============ ================ =========== ====== ==========
57833 14664 0 0 9.476
8MB / s lo coloca en los niveles que estaba obteniendo con ventanas explícitamente grandes iperf
. Sin embargo, curiosamente, 80 MB en 1273 búferes = un búfer de 64kB nuevamente. Un wirehark adicional muestra un buen RWIN variable que regresa del servidor (Factor de escala 256) que el cliente parece cumplir; entonces quizás ntttcp está informando erróneamente la ventana de envío.
Actualización 4 - 3 de julio
A pedido de @ karyhead, hice algunas pruebas más y generé algunas capturas más, aquí: https://www.dropbox.com/s/dtlvy1vi46x75it/iperf%2Bntttcp%2Bftp-pcaps-2014-07-03.zip
- Dos
iperf
s más , ambos desde Windows al mismo servidor Linux que antes (1.2.3.4): uno con un tamaño de socket de 128k y una ventana predeterminada de 64k (se restringe a ~ 5Mbit / s nuevamente) y uno con una ventana de envío de 1MB y un socket predeterminado de 8kb Talla. (escalas más altas) - Una
ntttcp
traza desde el mismo cliente de Windows a una instancia Server 2012R2 EC2 (1.2.3.5). aquí, el rendimiento escala bien. Nota: NTttcp hace algo extraño en el puerto 6001 antes de abrir la conexión de prueba. No estoy seguro de lo que está pasando allí. - Un seguimiento de datos FTP, cargando 20 MB de
/dev/urandom
un host Linux casi idéntico (1.2.3.6) usando Cygwinncftp
. De nuevo el límite está ahí. El patrón es muy similar usando Windows Filezilla.
Cambiar la iperf
longitud del búfer hace la diferencia esperada en el gráfico de secuencia de tiempo (muchas más secciones verticales), pero el rendimiento real no cambia.
fuente
netsh int tcp set global timestamps=enabled
Respuestas:
¿Ha intentado habilitar Compound TCP (CTCP) en sus clientes Windows 7/8.
Por favor lee:
Aumento del rendimiento del lado del remitente para la transmisión de alto BDP
http://technet.microsoft.com/en-us/magazine/2007.01.cableguy.aspx
Editar 30/06/2014
para ver si CTCP está realmente "activado"
es decir
CTCP aumenta agresivamente la ventana de envío
http://technet.microsoft.com/en-us/library/bb878127.aspx
fuente
Set-NetTCPSetting
con el-CongestionProvider
parámetro ... que acepta CCTP, DCTCP y Default. El cliente y los servidores de Windows utilizan diferentes proveedores de congestión predeterminados. technet.microsoft.com/en-us/library/hh826132.aspxiperf
y la ventana todavía nunca se extendió más allá de ~ 520kb. Algo más está limitando el CWND antes de que este algoritmo agresivo pueda mostrar algún beneficio.Aclarando el problema:
TCP tiene dos ventanas:
En el archivo de captura que proporcionó. Podemos ver que el búfer de recepción nunca se desborda:
Mi análisis es que el remitente no está enviando lo suficientemente rápido porque la ventana de envío (también conocida como la ventana de control de congestión) no se abre lo suficiente como para satisfacer el RWIN del receptor. En resumen, el receptor dice "Dame más", y cuando Windows es el remitente, no está enviando lo suficientemente rápido.
Esto se evidencia por el hecho de que en el gráfico anterior, el RWIN permanece abierto, y con el tiempo de ida y vuelta de .09 segundos y un RWIN de ~ 500,000 bytes, podemos esperar un rendimiento máximo de acuerdo con el producto de retraso de ancho de banda (500000 /0.09) * 8 = ~ 42 Mbit / s (y solo obtienes alrededor de ~ 5 en tu victoria para la captura de Linux).
¿Como arreglarlo?
No lo sé.
interface tcp set global congestionprovider=ctcp
Suena como lo correcto para mí porque aumentaría la ventana de envío (que es otro término para la ventana de congestión). Dijiste que eso no está funcionando. Entonces solo para asegurarme:netsh interface tcp show heuristics
. Creo que podría ser RWIN, pero no dice, así que tal vez juegue con deshabilitar / habilitar en caso de que afecte la ventana de envío.Para comenzar, probaría todos estos experimentos con todas las funciones de descarga eliminadas para eliminar la posibilidad de que los controladores de red estén reescribiendo / modificando algunas cosas (vigile la CPU mientras la descarga está desactivada). La estructura TCP_OFFLOAD_STATE_DELEGATED parece implicar al menos que la descarga de CWnd es al menos posible.
fuente
Ha habido una gran información aquí por @Pat y @Kyle. Definitivamente preste atención a la explicación de @ Kyle de las ventanas de recepción y envío de TCP, creo que ha habido cierta confusión al respecto. Para confundir aún más las cosas, iperf utiliza el término "ventana TCP" con la
-w
configuración que es un término ambiguo con respecto a la ventana deslizante de recepción, envío o global. Lo que realmente hace es configurar el búfer de envío de socket para la-c
instancia (cliente) y el búfer de recepción de socket en la-s
instancia (servidor). Ensrc/tcp_window_size.c
:Como Kyle menciona, el problema no es con la ventana de recepción en el cuadro de Linux, sino que el remitente no abre la ventana de envío lo suficiente. No es que no se abra lo suficientemente rápido, solo se limita a 64k.
El tamaño predeterminado del búfer de socket en Windows 7 es 64k. Esto es lo que dice la documentación sobre el tamaño del búfer de socket en relación con el rendimiento en MSDN
Ok, bla bla bla, ahora aquí vamos:
El rendimiento promedio de su prueba iperf más reciente usando la ventana de 64k es de 5.8Mbps. Eso es de Estadísticas> Resumen en Wireshark, que cuenta todos los bits. Probablemente, iperf cuenta el rendimiento de datos TCP que es 5.7Mbps. También vemos el mismo rendimiento con la prueba FTP, ~ 5.6Mbps.
El rendimiento teórico con un buffer de envío de 64k y RTT de 91ms es ... 5.5Mbps. Lo suficientemente cerca para mí.
Si miramos su prueba iperf de ventana de 1 MB, la tput es de 88.2 Mbps (86.2 Mbps solo para datos TCP). El rendimiento teórico con una ventana de 1 MB es de 87,9 Mbps. Nuevamente, lo suficientemente cerca para el trabajo del gobierno.
Lo que esto demuestra es que el búfer de socket de envío controla directamente la ventana de envío y que, junto con la ventana de recepción desde el otro lado, controla el rendimiento. La ventana de recepción anunciada tiene espacio, por lo que no estamos limitados por el receptor.
Espera, ¿qué pasa con este negocio de autoajuste? ¿Windows 7 no maneja esas cosas automáticamente? Como se ha mencionado, Windows maneja el autoescalado de la ventana de recepción, pero también puede manejar dinámicamente el búfer de envío. Volvamos a la página de MSDN:
iperf usa
SO_SNDBUF
cuando usa la-w
opción, por lo que el buffering dinámico de envío estaría deshabilitado. Sin embargo, si no lo usa,-w
entonces no lo haceSO_SNDBUF
. El búfer de envío dinámico debe estar activado de forma predeterminada, pero puede verificar:La documentación dice que puede deshabilitarlo con:
Pero eso no funcionó para mí. Tuve que hacer un cambio en el registro y establecerlo en 0:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD\Parameters\DynamicSendBufferDisable
No creo que deshabilitar esto ayude; es solo un FYI.
¿Por qué su escala de búfer de envío no supera los 64k predeterminados cuando envía datos a un cuadro de Linux con mucho espacio en la ventana de recepción? Gran pregunta Los núcleos de Linux también tienen una pila TCP de autoajuste. Al igual que T-Pain y Kanye hacen un dúo de autoajuste juntos, puede que no suene bien. Quizás haya algún problema con esas dos pilas TCP de autoajuste que se hablan entre sí.
Otra persona tuvo un problema como el suyo y pudo solucionarlo con una edición del registro para aumentar el tamaño predeterminado del búfer de envío. Desafortunadamente, eso ya no parece funcionar, al menos no me funcionó cuando lo probé.
En este punto, creo que está claro que el factor limitante es el tamaño del búfer de envío en el host de Windows. Dado que no parece estar creciendo dinámicamente correctamente, ¿qué debe hacer una niña?
Usted puede:
Descargo de responsabilidad: he pasado muchas horas investigando esto y es lo mejor de mi conocimiento y google-fu. Pero no juraría sobre la tumba de mi madre (todavía está viva).
fuente
Una vez que tenga la pila TCP ajustada, es posible que todavía tenga un cuello de botella en la capa Winsock. He descubierto que la configuración de Winsock (controlador de función auxiliar en el registro) hace una gran diferencia para las velocidades de carga (enviar datos al servidor) en Windows 7. Microsoft ha reconocido un error en el autoajuste TCP para sockets sin bloqueo, solo el tipo de socket que usan los navegadores ;-)
Agregue la clave DWORD para DefaultSendWindow y configúrelo en BDP o superior. Estoy usando 256000.
Cambiar la configuración de Winsock para las descargas podría ayudar: agregue una clave para DefaultReceiveWindow.
Puede experimentar con varias configuraciones de nivel de socket utilizando el Proxy Fiddler y los comandos para ajustar los tamaños de búfer de socket del cliente y del servidor:
fuente
Después de leer todo el análisis en las respuestas, este problema suena como si estuvieras ejecutando Windows7 / 2008R2, también conocido como Windows 6.1
La pila de red (TCP / IP y Winsock) en Windows 6.1 era terriblemente defectuosa y tenía una gran cantidad de errores y problemas de rendimiento que Microsoft eventualmente solucionó durante muchos años de revisión desde el lanzamiento inicial de 6.1.
La mejor manera de aplicar estas revisiones es tamizar manualmente todas las páginas relevantes en support.microsoft.com y solicitar y descargar manualmente las versiones LDR de las revisiones de la pila de red (hay muchas docenas de estas).
Para encontrar las revisiones relevantes, debe usar www.bing.com con la siguiente consulta de búsqueda
site:support.microsoft.com 6.1.7601 tcpip.sys
También debe comprender cómo funcionan los trenes de revisión LDR / GDR en Windows 6.1
En general, solía mantener mi propia lista de arreglos LDR (no solo arreglos de la pila de red) para Windows 6.1 y luego los aplicaba proactivamente a cualquier servidor / cliente de Windows 6.1 con el que me encontraba. Era una tarea que requería mucho tiempo verificar regularmente si hay nuevas revisiones LDR.
Afortunadamente, Microsoft ha detenido la práctica de las revisiones LDR con nuevas versiones del sistema operativo y las correcciones de errores ahora están disponibles a través de los servicios de actualización automática de Microsoft.
ACTUALIZACIÓN : solo un ejemplo de muchos errores de red en Windows7SP1: https://support.microsoft.com/en-us/kb/2675785
ACTUALIZACIÓN 2 : Aquí hay otra revisión que agrega un conmutador netsh para forzar el escalado de la ventana después de la segunda retransmisión de un paquete SYN (de forma predeterminada, el escalado de la ventana está deshabilitado después de que se retransmiten 2 paquetes SYN) https://support.microsoft.com/en- nosotros / kb / 2780879
fuente
Veo que esta es una publicación un poco más antigua, pero podría ayudar a otros.
En resumen, debe habilitar "Recibir ajuste automático de ventana":
CTCP no significa nada sin lo anterior habilitado.
Si deshabilita el "Ajuste automático de la ventana de recepción", se quedará atascado en un tamaño de paquete de 64 KB que tiene un impacto negativo sobre los RTT largos en conexiones de banda ancha alta. También puede experimentar con la opción "restringida" y "altamente restringida".
Muy buena referencia: https://www.duckware.com/blog/how-windows-is-killing-internet-download-speeds/index.html
fuente
Estaba experimentando un problema similar con los clientes de Windows (Windows 7). Revisé la mayoría de las depuraciones por las que ha pasado, deshabilitando el algoritmo de Nagle, la descarga de la chimenea TCP y muchos otros cambios de configuración relacionados con TCP. Ninguno de ellos tuvo ningún efecto.
Lo que finalmente lo arregló para mí fue modificar la ventana de envío predeterminada en el registro del servicio AFD. El problema parece estar relacionado con el archivo afd.sys. Probé varios clientes, algunos exhibieron la carga lenta y otros no, pero todos eran máquinas con Windows 7. Las máquinas que exhibían el comportamiento lento tenían la misma versión AFD.sys. La solución alternativa de registro es necesaria para las computadoras con ciertas versiones de AFD.sys (lo siento, no recuerdo los números de versión).
HKLM \ CurrentControlSet \ Services \ AFD \ Parámetros
Agregar - DWORD - DefaultSendWindow
Valor - Decimal - 1640960
Ese valor es algo que encontré aquí: https://helpdesk.egnyte.com/hc/en-us/articles/201638254-Upload-Speed-Slow-over-WebDAV-Windows-
Creo que para usar el valor adecuado, debe calcularlo usted mismo usando:
p.ej. Carga anunciada: 15 Mbps = 15,000 Kbps
(15000/8) * 1024 = 1920000
Por lo que entiendo, el software del cliente generalmente debería anular esta configuración en el registro, pero si no lo hacen, se usa el valor predeterminado, y aparentemente el valor predeterminado es muy bajo en algunas versiones del archivo AFD.sys.
Me di cuenta de que la mayoría de los productos de MS tenían un problema de carga lenta (IE, Mini-redirector (WebDAV), FTP a través del Explorador de Windows, etc.) Al usar software de terceros (por ejemplo, Filezilla) no tuve las mismas ralentizaciones .
El AFD.sys afecta a todas las conexiones Winsock, por lo que esta solución debería aplicarse a FTP, HTTP, HTTPS, etc.
Además, esta solución también se enumeró anteriormente en alguna parte, por lo que no quiero darme el crédito si funciona para alguien, sin embargo, había tanta información en este hilo que temí que se hubiera pasado por alto.
fuente
Bueno, me he encontrado con una situación similar (mi pregunta aquí ), y al final tuve que deshabilitar la heurística de escalado de TCP, configurar manualmente el perfil de autoajuste y habilitar CTCP:
fuente
No tengo suficientes puntos para comentar, así que publicaré una "respuesta" en su lugar. Estoy teniendo lo que parece ser un problema similar / idéntico (vea la pregunta del servidor por defecto aquí ). Mi (y probablemente su) problema es el búfer de envío del cliente iperf en Windows. No crece más allá de 64 KB. Se supone que Windows aumenta dinámicamente el búfer cuando el proceso no lo dimensiona explícitamente. Pero ese crecimiento dinámico no está sucediendo.
No estoy seguro acerca de su gráfico de escala de ventana que muestra la ventana que se abre hasta 500,000 bytes para su caso de Windows "lento". Esperaba ver ese gráfico abierto a solo ~ 64,000 bytes dado que está limitado a 5 Mbps.
fuente
Este es un hilo fascinante y coincide exactamente con los problemas que he tenido al usar Win7 / iperf para probar el rendimiento en tuberías largas y gruesas.
La solución para Windows 7 es ejecutar el siguiente comando tanto en el servidor iperf como en el cliente.
netsh interface tcp set global autotuninglevel = experimental
NB: antes de hacer esto, asegúrese de registrar el estado actual del ajuste automático:
interfaz netsh tcp show global
Nivel de autoajuste de la ventana de recepción: deshabilitado
Luego ejecute el servidor / cliente iperf en cada extremo de la tubería.
Restablezca el valor de ajuste automático después de sus pruebas:
netsh interface tcp set global autotuninglevel =
fuente