He estado luchando para solucionar un problema de rendimiento con un recurso compartido SMB / CIFS al realizar pequeñas escrituras.
Primero, permítame describir mi configuración de red actual:
Servidor
- Synology DS215j (con soporte SMB3 habilitado)
Clientes (misma computadora con cable de arranque dual Gig-E)
- Ubuntu 14.04.5 LTS, Trusty Tahr
- Windows 8.1
smb.conf
[global]
printcap name=cups
winbind enum groups=yes
include=/var/tmp/nginx/smb.netbios.aliases.conf
socket options=TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536
security=user
local master=no
realm=*
passdb backend=smbpasswd
printing=cups
max protocol=SMB3
winbind enum users=yes
load printers=yes
workgroup=WORKGROUP
Actualmente estoy probando el rendimiento de escritura pequeña con el siguiente programa escrito en C ++ (en GitHub aquí ):
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main(int argc, char* argv[])
{
ofstream outFile(argv[1]);
for(int i = 0; i < 1000000; i++)
{
outFile << "Line #" << i << endl;
}
outFile.flush();
outFile.close();
return 0;
}
Configuración de montaje de Linux:
//192.168.1.10/nas-main on /mnt/nas-main type cifs (rw,noexec,nodev)
Programa en tiempo de ejecución en Linux (picos de salida de red a ~ 100Mbps):
$ time ./nas-write-test /mnt/nas-main/home/will/test.txt
real 0m0.965s
user 0m0.148s
sys 0m0.672s
Instantánea PCAP que muestra el agrupamiento de muchas líneas en un solo paquete TCP:
Programe el tiempo de ejecución en Windows medido por PowerShell:
> Measure-Command {start-process .\nas-write-test.exe -argumentlist "Z:\home\will\test-win.txt" -wait}
Days : 0
Hours : 0
Minutes : 9
Seconds : 29
Milliseconds : 316
Ticks : 5693166949
TotalDays : 0.00658931359837963
TotalHours : 0.158143526361111
TotalMinutes : 9.48861158166667
TotalSeconds : 569.3166949
TotalMilliseconds : 569316.6949
Instantánea de PCAP en Windows que muestra una sola línea por solicitud de escritura SMB:
Este mismo programa tarda unos 10 minutos (~ 2.3Mbps) en Windows. Obviamente, el PCAP de Windows muestra una conversación SMB muy ruidosa con una eficiencia de carga muy baja.
¿Hay alguna configuración en Windows que pueda mejorar el rendimiento de escritura pequeña? Al observar las capturas de paquetes, parece que Windows no almacena las escrituras correctamente e inmediatamente envía los datos línea por línea. Mientras que, en Linux, los datos están fuertemente almacenados y, por lo tanto, tienen un rendimiento muy superior. Avíseme si los archivos PCAP serían útiles y puedo encontrar una manera de cargarlos.
Actualización 27/10/16:
Como mencionó @sehafoc, reduje la max protocol
configuración de los servidores Samba a SMB1 con lo siguiente:
max protocol=NT1
La configuración anterior resultó exactamente en el mismo comportamiento.
También eliminé la variable de Samba al crear un recurso compartido en otra máquina con Windows 10, y también exhibe el mismo comportamiento que el servidor Samba, por lo que estoy empezando a creer que este es un error de escritura en caché con los clientes de Windows en general.
Actualización: 10/06/17:
Captura completa de paquetes de Linux (14 MB)
Captura completa de paquetes de Windows (375 MB)
Actualización: 12/10/17:
También configuré un recurso compartido NFS y Windows también escribe sin almacenamiento en búfer para esto. Entonces, definitivamente, es un problema subyacente del cliente de Windows, por lo que puedo decir, lo cual es definitivamente desafortunado: - /
¡Cualquier ayuda sería apreciada!
No tengo suficiente reputación para dejar un comentario (que creo que sería mejor dado el nivel de verificación de esta respuesta).
Noté que una gran variación en el rastreo de nivel de Linux vs Windows es que está utilizando SMB1 en Linux y SMB2 en Windows. Quizás el mecanismo de bloqueo por lotes funcione mejor en SMB1 samba que la implementación de arrendamiento exclusiva SMB2. En ambos casos, esto debería permitir cierta cantidad de almacenamiento en caché del lado del cliente.
1) Quizás intente establecer un nivel de protocolo máximo más bajo en Samba para probar ventanas con SMB1 2) Valide que se obtengan oplocks o arrendamientos exclusivos
Espero que esto ayude :)
fuente
El rendimiento de las operaciones de archivos remotos, como lectura / escritura, utilizando el protocolo SMB puede verse afectado por el tamaño de los buffers asignados por servidores y clientes. El tamaño del búfer determina la cantidad de viajes de ida y vuelta necesarios para enviar una cantidad fija de datos. Cada vez que se envían solicitudes y respuestas entre el cliente y el servidor, la cantidad de tiempo necesario es al menos igual a la latencia entre ambos lados, lo que podría ser muy significativo en el caso de la red de área amplia (WAN).
Búfer SMB: MaxBufferSize se puede configurar mediante la siguiente configuración de registro:
Tipo de datos:
REG_DWORD
Rango: 1024 a 65535 (Elija el valor según su requisito por encima de 5000)
PERO SMB SIGNING afecta el tamaño máximo permitido del búfer. Por lo tanto, también debemos deshabilitar la firma de SMB para lograr nuestro objetivo. El siguiente registro debe crearse en el lado del servidor y, si es posible, en el lado del cliente también.
Nombre del valor:
EnableSecuritySignature
Tipo de datos:
REG_DWORD
Datos: 0 (deshabilitar), 1 (habilitar)
fuente
Fenómeno interesante Esto es lo que intentaría: no tengo idea si esto realmente ayuda. Si se tratara de mi máquina, miraría mucho los contadores de SMB. Uno de ellos se mostrará la causa.
Más cosas para probar
Agregar más hilos de trabajo
En caso de que SMB_RDR obtenga una solicitud de E / S de escritura por línea (lo que no debería suceder aquí), puede ser útil agregar algunos subprocesos al motor de ejecución.
Establezca "AdditionalCriticalWorkerThreads" en 2, luego en 4.
El valor predeterminado es 0, lo que significa que no se agregan subprocesos de trabajo de kernel críticos adicionales. Lo cual normalmente está bien. Este valor afecta el número de subprocesos que la caché del sistema de archivos utiliza para las solicitudes de lectura anticipada y de escritura diferida. Elevar este valor puede permitir más E / S en cola en el subsistema de almacenamiento (lo cual es bueno, cuando desea escribir línea por línea), pero es más costoso para la CPU.
Agregar más longitud de cola
El aumento del valor "AdditionalCriticalWorkerThreads" aumenta el número de subprocesos que el servidor de archivos puede usar para atender solicitudes concurrentes .
El valor predeterminado es 20. Una indicación de que es posible que sea necesario aumentar el valor es si las colas de trabajo SMB2 crecen mucho (el contador "Colas de trabajo del servidor \ Longitud de la cola \ SMB2 *" debe ser <100).
fuente