Estou projetando um sistema para lidar com 10000 conexões TCP por segundo. Em quais problemas vou me deparar?

18

Eu tenho uma caixa de 8 núcleos relativamente nova executando o CentOS. Eu gostaria de desenvolver um servidor de estatísticas que use TCP. É muito simples, aceita uma conexão TCP, incrementa um contador e fecha a conexão. O problema é que ele precisa fazer isso em pelo menos 10 mil solicitações por segundo. Suspeito que CPU / Memória não seja um problema, mas estou mais preocupado com limites artificiais (como conexões semi-abertas) que talvez precise configurar no meu servidor para permitir esse tipo de volume. Então, isso é possível? Quais configurações devo estar ciente? Minha NIC não será capaz de lidar com isso?


fonte
11
Certifique-se não tópicos de desova para cada conexão de entrada, ele vai matar o desempenho
11
+1 para relatar seus resultados finais aqui :)
agsamek

Respostas:

17

Isso é conhecido como o problema c10k . Essa página tem muitas informações boas sobre os problemas que você encontrará.

Greg Hewgill
fonte
sim, bom link!
sybreon 29/09/09
11
Eu esperaria ver mais / problemas diferentes dos mencionados na página c10k. Estabelecer e fechar 10 mil conexões por segundo é diferente de ter 10 mil conexões abertas. As conexões que permanecem no estado TIME_WAIT seriam uma, atingir o limite de pendências para um soquete de escuta poderia ser outra. E não ficaria surpreso se esse caso de uso não tivesse recebido tanto perfil / otimização no código do kernel quanto o caso mais comum de conexões abertas de 10k.
cmeerw
2

você deve ser capaz de fazê-lo [embora isso seja provavelmente uma má ideia].

no appserv resina eu posso obter ~ 5k req / seg no quad core 2.6ghz xeon. Os pedidos chamam um servlet simples que lê 1 linha do mysql e envia uma resposta xml muito pequena.

teste foi realizado com

ab -n 10000 -c 16 http://some/url/

Resultado dos testes:

Concurrency Level:      16
Time taken for tests:   1.904 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      3190000 bytes
HTML transferred:       1850000 bytes
Requests per second:    5252.96 [#/sec] (mean)
Time per request:       3.046 [ms] (mean)
Time per request:       0.190 [ms] (mean, across all concurrent requests)
Transfer rate:          1636.42 [Kbytes/sec] received

mas acho que você ficará muito melhor usando o programa c simples, sem gerar novos threads para cada solicitação. O link de Greg Hewgill deve lhe dar uma boa idéia.

mesmo durante o teste prolongado, não tenho problemas com a conectividade [mencionados soquetes entreabertos]; O teste é executado entre duas caixas Linux conectadas à Ethernet Gigabit [embora, como você vê, a largura de banda não seja um gargalo].

pQd
fonte
Suas conexões estão fechadas após cada resposta como os OPs? O ab está enviando Connection: close header?
Nate
11
@ Nate é http 1.0 - conexão única para cada solicitação http.
pQd
1

Você pode estar interessado em um limite do kernel do Linux que atingi ao testar o Apache. No meu caso, o kernel produziu algumas mensagens de erro úteis, então meu conselho é escrever seu programa e, se você parece estar atingindo um limite, preste atenção nos logs do kernel.

Ben Williams
fonte
0

Eu usaria o UDP em vez do TCP, se possível. Deve ser mais leve e, portanto, escalar melhor.

Zimmy-DUB-Zongy-Zong-DUBBY
fonte
Concordo. UDP seria muito mais leve
fpmurphy
11
O UDP tem suas desvantagens, como verificações de remetente e entrega, portanto, deve-se considerá-las antes de usar o UDP na produção.
SaveTheRbtz 30/09/09
0

Seu nic deve ser capaz de lidar com isso, mas eu questiono o design de ter 10k novas conexões TCP por segundo; se você estiver criando / destruindo conexões com tanta rapidez, a) mantenha-as abertas por mais tempo ou b) use o UDP.

No caso de você ter 1 milhão de clientes que precisam fazer uma consulta periodicamente, mas onde a carga atinge 10k por segundo, o UDP provavelmente é uma escolha melhor.

No caso de você ter apenas 10 mil clientes que precisam fazer uma consulta a cada segundo, eles podem manter abertas as conexões existentes e reutilizá-las. Isso seria muito mais gentil com o sistema operacional e também produziria muito menos latência, pois não exigiria um novo aperto de mão a cada vez.

No caso de você ter 10 mil solicitações por segundo, imagino que você tenha um balanceador de carga de front-end de qualquer maneira, portanto, será necessário testá-lo também.

(Nota: acho que isso pertencia ao Stack Overflow)

MarkR
fonte