Windows 2008 Server em velocidades ethernet mistas - faça o download do compartilhamento lento, mas o TCP é simples e rápido

6

Eu tenho um servidor x64 do Windows Server 2008 R2 que é o controlador AD e o servidor de arquivos. Eu tenho um problema que os clientes do Windows XP experimentam terrivelmente lento (menos de 10Mbps, realmente menos de dez-mega bits -pés-segundo) download de arquivos de um compartilhamento.

O servidor está conectado a um comutador de 1 Gbps usando uma placa Nvidia NForce de 1 Gbps e o cliente é conectado usando um cartão embutido de 100 Mbps.

Esse download lento também pode ser visto quando eu inicializei o computador cliente do CentOS Linux 5.5 Live-USB e usei o smbclient para fazer o download. Mas o download de um compartilhamento Samba no servidor Linux, que também é conectado usando um link de 1 Gbps, é rápido.

O que é muito estranho Eu criei um par de programas (anexados abaixo) que testam o throughput TCP simples em C #, e eles estão funcionando como esperado - em cerca de 89Mbps.

Desativei o firewall no cliente e estou usando dot_nc_l 21000 > NIL no cliente e dot_nc [client_ip] < 100m.dat no servidor Windows. E recebo cerca de 9 segundos, quando copiar o mesmo arquivo de 100MB do compartilhamento leva mais de 2 minutos.

Como eliminar isso?

Algumas imagens geradas com o wireshark no cliente Linux:

Download do arquivo de 100 MB do servidor de arquivos CIFS do Windows 2008 conectado com NIC de 1 Gbps ao cliente Centos 5 Linux conectado com NIC de 100 Mbps com smbclient:

Downloaddoarquivode100MBdoservidordearquivosCIFSdoFedoraLinuxnoSambaconectadocomNICde1GbpsaoclienteCentos5LinuxconectadocomNICde100Mbpscomsmbclient(mesmaescalaacima):

Aqui estão estes programas (ligados são compilados usando o gmcs da mono, requerem o .NET2):

dot_nc.cs

using System;
using System.IO;
using System.Diagnostics;
using System.Net.Sockets;

public class dot_nc
{
 public static void Main(string[] args) {
  string hostname = args[0];
  int port = int.Parse(args[1]);

  Stopwatch stopwatch = new Stopwatch();

  stopwatch.Start();
  TcpClient client = new TcpClient(hostname, port);
  stopwatch.Stop();
  Console.WriteLine("Connection: {0}ms", stopwatch.ElapsedMilliseconds);

  stopwatch.Reset();
  stopwatch.Start();
  byte[] buffer = new byte[4096];
  {
   Stream stdin = Console.OpenStandardInput();
   NetworkStream netout = client.GetStream();
   while ( true ) {
    int bytesread = stdin.Read(buffer, 0, buffer.Length);
    if ( bytesread <= 0 ) {
     break;
    }
    netout.Write(buffer, 0, bytesread);
   }
  }
  stopwatch.Stop();
  Console.WriteLine("Sending: {0}ms", stopwatch.ElapsedMilliseconds);
  client.Close();
 }
}

dot_nc_l.cs

using System;
using System.IO;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;

public class dot_nc
{
 public static void Main(string[] args) {
  int port = int.Parse(args[0]);

  TcpListener server = new TcpListener(IPAddress.Any, port);
  server.Start();
  TcpClient client = server.AcceptTcpClient();
  NetworkStream netin = client.GetStream();

  byte[] buffer = new byte[4096];

  Stream stdout = Console.OpenStandardOutput();
  int processed_bytes = 0;
  int processed_chunks = 0;
  while ( true ) {
   int bytesread = netin.Read(buffer, 0, buffer.Length);
   if ( bytesread <= 0 ) {
    break;
   }
   stdout.Write(buffer, 0, bytesread);
   processed_bytes += bytesread;
   processed_chunks++;
  }
  netin.Close();
  client.Close();
  server.Stop();
  Console.Error.WriteLine(
   "Received: {0} chunks of data of {1} average size", 
   processed_chunks, processed_bytes/processed_chunks
  );
 }
}
    
por Tometzky 06.12.2010 / 20:45

6 respostas

5

O problema foi causado por:

  • buffers de pacotes muito pequenos em um switch gigabit barato;
  • algoritmo de prevenção de congestionamento inadequado usado nos Serviços de arquivos do Windows Server 2008;
  • desativou o controle de fluxo no adaptador de rede (ele foi desativado por padrão).

Como o controle de fluxo estava desabilitado, o Windows enviava pacotes até o tamanho da janela em um lote usando conexão de 1 Gbps. Como o cliente de 100 Mbps recebe pacotes muito mais lentamente, quase todos os dados até o tamanho da janela precisavam ser armazenados em buffer por um comutador. Como este switch barato tem buffers muito pequenos (tamanhos de buffer não são sequer indicados nas especificações, mas tem que ser inferior a 64kB por porta, como até mesmo desabilitar o dimensionamento de janela não ajudou) teve que soltar os pacotes em excesso. A perda de pacotes causou um atraso de cerca de 0,25s visto em um gráfico. Mas o algoritmo de prevenção de congestionamento, usado no File Services, ou a falta dele, não reduziu o tamanho da janela TCP, então o próximo lote de pacotes não foi menor - ele congestionou a conexão novamente causando congestion collapse .

Conexões TCP padrão (não Serviços de Arquivo) devem usar algoritmo de controle de congestionamento diferente e não ficar congestionadas repetidamente. Eu suponho que tratar os serviços de arquivos especialmente pela pilha TCP do Windows ajuda nos benchmarks, por exemplo, no Samba.

Então as soluções são:

  • Ativar controle de fluxo nas propriedades do adaptador de rede. Não é uma solução ideal, pois qualquer transferência de serviços de arquivo para cliente de 100Mbps também reduzirá as transferências simultâneas para clientes de 1Gbps para menos de 100Mbps velocidades.

  • Ou conecte clientes de 100 Mbps a um switch de classe empresarial com buffers muito maiores. Essa é uma solução que usei. Tenho um switch "3Com SuperStack 3 3300 SM" de 10 anos com uma porta Ethernet MTB-B de 1000Base-SX de fibra ótica. Comprei um módulo mini-Gbic Cisco 1000BASE-SX (MGBSX1) com porta LC para meu switch gigabit Linksys e cabo de fibra multimodo LC / MT-RJ (cerca de US $ 150 para ambos) e conectei todos os 100Mbps clientes para este switch 3com. Também habilitei o controle de fluxo, mas ele não deve causar lentidão com nenhum cliente de 100 Mbps conectado.

Obrigado a SpacemanSpiff , cujos comentários ajudaram a resolver isso.

    
por 29.12.2011 / 10:55
1

O servidor do Windows tem a assinatura SMB ativada? A assinatura SMB adiciona lentidão e é habilitado por padrão nos controladores de domínio.

    
por 06.12.2010 / 21:00
1

Pode ser a placa / comutador de 100 Mbps? Você menciona que o mesmo cliente funciona corretamente quando está em 1Gbps.

    
por 06.12.2010 / 21:29
1

Parece um problema de rede de nível inferior. Meus palpites:

  • Problemas de incompatibilidade de duplex. Isso certamente traria um pouco o desempenho. No lado do Linux, use o comando ethtool para verificar se você está negociando a 100 Mbps / Full Duplex. Se o seu cartão negocia em 100 / Half, e o switch acha que a conexão é 100 / Full, então haverá todos os tipos de problemas. Você pode querer experimentar forçar 100 / Full em vez de negociar automaticamente a velocidade (lembre-se de forçar 100 / Full no switch e no sistema)
  • Também pode ser um problema de buffer na placa de rede do cliente ou no comutador. Eu vi drivers de placa de rede não alocar espaço de buffer suficiente e causar problemas com velocidade. Eu imagino que o mesmo tipo de problema poderia acontecer no switch. Muito mais difícil de diagnosticar, além de trocar de equipamento.
por 13.12.2010 / 02:54
0

Você pode tentar copiar via esetutil (se você tiver um servidor Exchange lá)

Verifique isso: link

Isso pode ser um teste se você copiar arquivos grandes do cliente para o servidor ou vice-versa para testar se o esetutil obtém melhor desempenho.

também tive problemas semelhantes com um servidor Windows 2008 e Linux com uma opção chamada NetDMA (última seção). Isso resolveu meus problemas (era um adaptador de rede Broadcom com formação de equipe)

Como habilitar e desabilitar o NetDMA no Windows Server 2008 Para ativar ou desativar o NetDMA, siga estas etapas: Clique em Iniciar, clique em Executar, digite regedit e, em seguida, clique em OK. Localize a seguinte subchave do Registro e clique nela: HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters Clique duas vezes na entrada de registro EnableTCPA. Observação Se essa entrada do Registro não existir, clique com o botão direito do mouse em Parâmetros, aponte para Novo, clique em Valor DWORD, digite EnableTCPA e pressione ENTER. Para habilitar o NetDMA, digite 1 na caixa dados do valor e, em seguida, clique em OK. Para desabilitar o NetDMA, digite 0 na caixa Dados do valor e clique em OK. Se a entrada de registro EnableTCPA não existir, ative a funcionalidade NetDMA. Os produtos de terceiros mencionados neste artigo são fabricados por empresas independentes da Microsoft. A Microsoft não oferece garantia, implícita ou não, sobre o desempenho ou a confiabilidade desses produtos

do Suporte Microsoft KB 951037

    
por 16.12.2010 / 12:11
0

Verifique se o BIOS dos seus servidores / clientes tem um parâmetro "CPU C State" (provavelmente dentro da categoria de economia de energia). Se presente, tente configurar esse parâmetro para DISABLE.

    
por 23.10.2011 / 16:44