Tenho lutado para corrigir um problema de desempenho com um compartilhamento SMB / CIFS ao realizar pequenas gravações.
Primeiro, deixe-me descrever minha configuração de rede atual:
Servidor
- Synology DS215j (com suporte SMB3 ativado)
Clientes (mesmo Gig-E com fio com inicialização dupla)
- 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
Atualmente, estou testando o pequeno desempenho de gravação com o seguinte programa escrito em C ++ (no GitHub aqui ):
#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;
}
Configuração de montagem do Linux:
//192.168.1.10/nas-main on /mnt/nas-main type cifs (rw,noexec,nodev)
Programe o tempo de execução no Linux (atinge a saída da rede em ~ 100Mbps):
$ time ./nas-write-test /mnt/nas-main/home/will/test.txt
real 0m0.965s
user 0m0.148s
sys 0m0.672s
Instantâneo PCAP mostrando a divisão de várias linhas em um único pacote TCP:
Programe o tempo de execução no Windows, conforme medido pelo 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âneo PCAP no Windows mostrando uma única linha por solicitação de gravação SMB:
Este mesmo programa leva cerca de 10 minutos (~ 2.3Mbps) no Windows. Obviamente, o PCAP do Windows mostra uma conversa SMB muito barulhenta com eficiência de carga útil muito baixa.
Existem configurações no Windows que podem melhorar o desempenho de gravação pequena? Parece que, ao observar as capturas de pacotes, o Windows não armazena em buffer as gravações corretamente e envia imediatamente os dados, uma linha por vez. Considerando que, no Linux, os dados são fortemente armazenados em buffer e, portanto, têm desempenho muito superior. Deixe-me saber se os arquivos PCAP seriam úteis e posso encontrar uma maneira de enviá-los.
Atualização 10/27/16:
Conforme mencionado por @sehafoc, reduzi a max protocol
configuração de servidores Samba para SMB1 com o seguinte:
max protocol=NT1
A configuração acima resultou exatamente no mesmo comportamento.
Também removi a variável do Samba criando um compartilhamento em outra máquina Windows 10, e ela também exibe o mesmo comportamento do servidor Samba, por isso estou começando a acreditar que esse é um erro de cache de gravação nos clientes Windows em geral.
Atualização: 10/06/17:
Captura completa de pacotes do Linux (14 MB)
Captura total de pacotes do Windows (375MB)
Atualização: 10/12/17:
Também configurei um compartilhamento NFS e o Windows escreve sem buffer para isso também. Portanto, é definitivamente um problema subjacente do cliente Windows, até onde eu sei, o que é definitivamente lamentável: - /
Qualquer ajuda seria apreciada!
Não tenho reputação suficiente para deixar um comentário (o que acho melhor, dado o nível de verificação desta resposta).
Percebo que uma grande variação no seu rastreamento de nível Linux x Windows é que você está usando SMB1 no Linux e SMB2 no Windows. Talvez o mecanismo de bloqueio de lote tenha um desempenho melhor no samba SMB1 do que na implementação de concessão exclusiva do SMB2. Nos dois casos, isso deve permitir uma certa quantidade de cache do lado do cliente.
1) Talvez tente definir um nível máximo de protocolo máximo no Samba para testar janelas com o SMB1.
Espero que isto ajude :)
fonte
O desempenho das operações remotas de arquivo, como leitura / gravação, usando o protocolo SMB, pode ser afetado pelo tamanho dos buffers alocados pelos servidores e clientes. O tamanho do buffer determina o número de viagens de ida e volta necessárias para enviar uma quantidade fixa de dados. Sempre que solicitações e respostas são enviadas entre cliente e servidor, o tempo gasto é igual a pelo menos a latência entre os dois lados, o que pode ser muito significativo no caso da WAN (Wide Area Network).
Buffer SMB - O MaxBufferSize pode ser configurado através da seguinte configuração do Registro:
Tipo de dados:
REG_DWORD
Faixa: 1024 a 65535 (escolha o valor conforme sua exigência acima de 5000)
MAS SMB SIGNING afeta o tamanho máximo permitido do buffer. Portanto, precisamos desativar a assinatura SMB e alcançar nosso objetivo. O registro a seguir precisa ser criado no servidor e, se possível, no cliente também.
Nome do valor:
EnableSecuritySignature
Tipo de dados:
REG_DWORD
Dados: 0 (desativar), 1 (ativar)
fonte
Fenômeno interessante. Aqui está o que eu tentaria - não tenho idéia se isso realmente ajuda. Se fosse minha máquina, eu assistiria extensivamente aos perfcounters de pequenas e médias empresas. Um deles vai mostrar a causa.
Mais coisas para experimentar
Adicionar mais segmentos de trabalho
Caso o SMB_RDR atenda uma solicitação de E / S de gravação por linha (o que não deve acontecer aqui), pode ser útil adicionar alguns encadeamentos ao mecanismo de execução.
Defina "AdditionalCriticalWorkerThreads" para 2 e depois para 4.
O padrão é 0, o que significa que nenhum encadeamento crítico adicional do operador do kernel foi adicionado. O que geralmente está ok. Esse valor afeta o número de encadeamentos que o cache do sistema de arquivos usa para solicitações de leitura antecipada e gravação posterior. O aumento desse valor pode permitir mais E / S em fila no subsistema de armazenamento (o que é bom quando você deseja gravar linha por linha), mas é mais caro para a CPU.
Adicionar mais comprimento da fila
Aumentar o valor "AdditionalCriticalWorkerThreads" aumenta o número de threads que o servidor de arquivos pode usar para atender a solicitações simultâneas .
O padrão é 20. Uma indicação de que o valor pode precisar ser aumentado é se as filas de trabalho do SMB2 estiverem crescendo muito (o perfcounter 'Filas de trabalho do servidor \ Comprimento da fila \ SMB2 *'. Deve ser <100).
fonte