Estou tentando configurar o Varnish na frente do Drupal e estou executando alguns testes rápidos do Apache Bench para ver que tipo de melhoria estou obtendo.
O comando ab específico que estou executando é: ab -n 15000 -c 300 -k -H 'Accept-Encoding: gzip,deflate' www.mysite.tld/some-page
Uma vez que estabeleço uma simultaneidade superior a 300, começo a ver um resultado muito longo nos resultados:
Percentage of the requests served within a certain time (ms)
50% 2
66% 4
75% 4
80% 5
90% 7
95% 19
98% 45
99% 246
100% 5016 (longest request)
Essa cauda longa fica cada vez pior à medida que a concorrência aumenta, mas sempre parece ocorrer após 95% das conexões (dar ou receber).
Para o mesmo comando ab, mas com c em 500:
50% 1
66% 1
75% 1
80% 2
90% 5
95% 22
98% 365
99% 5060
100% 5061 (longest request)
Para c = 1000:
50% 1
66% 1
75% 2
80% 2
90% 5
95% 39
98% 5061
99% 27867
100% 27885 (longest request)
Eu alterei essas configurações do Varnish:
thread_pool_add_delay 1 [milliseconds]
thread_pool_max 5000 [threads]
thread_pool_min 500 [threads]
Tanto a máquina de verniz quanto a máquina que estou usando para teste estão no mesmo subdomínio e, na verdade, são ambas as máquinas virtuais no mesmo vmsphere. Usar o cerco mostra um padrão similar.
Por que esta cauda longa? Como posso me livrar disso?
EDITAR
Eu vejo essas mensagens no dmesg enquanto benchmarking:
[1469125.946204] TCP: Possible SYN flooding on port 80. Sending cookies.
[1469203.735802] TCP: Possible SYN flooding on port 80. Sending cookies.
[1469276.171367] TCP: Possible SYN flooding on port 80. Sending cookies.
E muitas vezes vejo coisas interessantes com sockets:
$ netstat -ant | grep 80 | awk '{print $6}' | sort | uniq -c | sort -n
1 TIME_WAIT
2 LISTEN
257 ESTABLISHED
437 CLOSE_WAIT
Enquanto o benchmarking, normalmente, ele passa pelos pedidos de 0 a 13500 e depois é muito, muito lento, apenas às vezes chegando a 15000. Se não conseguir, as conexões vão para CLOSE_WAIT - presumivelmente porque os tempos do Apache Bench fora, então o socket não está realmente fechado. Mas enquanto espera, geralmente há um monte de soquetes esperando em ESTABLISHED.
Existe algo acontecendo onde o kernel está enviando de volta os cookies syn, o que de alguma forma está fazendo com que meus clientes time e tente novamente?
EDIT 2
Embora seja uma ideia terrível na prática, tentei desativar os cookies syn:
sysctl -n net.ipv4.tcp_syncookies = 0
Isso fornece um resultado significativamente melhor - para c = 1000, n = 25000, os resultados parecem virtualmente os mesmos que c = 500, n = 15000 acima.
No entanto, também percebi que, se estou atendendo a 3 mil solicitações por segundo, estou realmente prestes a atingir o limite de meu canal de rede de saída. Então, eu provavelmente configurarei meus parâmetros de volta para seus padrões e não me preocuparei muito com meus resultados de benchmark. Mas eu continuo muito curioso sobre a) por que os cookies syn causariam essa lentidão, quando há bastante cpu em ambas as máquinas eb) porque, mesmo com syn cookies desativados, ainda vejo um resultado similar, apenas com valores c e mais altos.