Estoy corriendo un relativamente bajos-el sitio de tráfico que experimenta un gran aumento en los visitantes una vez a la semana después de una actualización del sitio. Durante este pico, el rendimiento del sitio es muy pobre en comparación con el resto de la semana. La realidad de la carga en los servidores sigue siendo muy baja, de forma fiable en el 10% de la CPU y menos de 30% de RAM (el hardware debe ser completa excesivo para lo que realmente estamos haciendo), pero por alguna razón Apache parece ser incapaz de lidiar con la cantidad de solicitudes. Estamos ejecutando apache 2.2.3 en RHEL 5.7, kernel 2.6.18-274.7.1.el5, x86_64.
Intentar reproducir este comportamiento durante las horas de descanso con ab, estoy encontrando una importante caída en el rendimiento cuando se excede aproximadamente 256 usuarios. Ejecución de la prueba con el menor uso posible caso que se me ocurrió (archivo de texto estático ser recuperada, de 223 bytes en total) rendimiento es siempre normal, con 245 solicitudes simultáneas:
Connection Times (ms)
min mean[+/-sd] median max
Connect: 15 25 5.8 24 37
Processing: 15 65 22.9 76 96
Waiting: 15 64 23.0 76 96
Total: 30 90 27.4 100 125
Percentage of the requests served within a certain time (ms)
50% 100
66% 108
75% 111
80% 113
90% 118
95% 120
98% 122
99% 123
100% 125 (longest request)
Pero tan pronto como me trinquete hasta 265 solicitudes simultáneas, un subconjunto de ellos empezar a tomar una absurda cantidad de tiempo para completar:
Connection Times (ms)
min mean[+/-sd] median max
Connect: 13 195 692.6 26 3028
Processing: 15 65 21.3 72 100
Waiting: 15 65 21.3 71 99
Total: 32 260 681.7 101 3058
Percentage of the requests served within a certain time (ms)
50% 101
66% 108
75% 112
80% 116
90% 121
95% 3028
98% 3040
99% 3044
100% 3058 (longest request)
Estos resultados son muy consistentes a través de múltiples pistas. Ya que no hay otro tráfico que va a la caja, no estoy seguro de que, precisamente, donde el duro de corte sería, si es que la hay, pero parece ser sospechosamente cerca de 256.
Naturalmente, yo supuse que esto era causado por el hilo límite en prefork, así que me fui por delante y ajustar la configuración para duplicar el número de subprocesos disponibles y para evitar que el grupo de subprocesos de crecimiento y reducción de unneccessarily:
<IfModule prefork.c>
StartServers 512
MinSpareServers 512
MaxSpareServers 512
ServerLimit 512
MaxClients 512
MaxRequestsPerChild 5000
</IfModule>
mod_status confirma que ahora estoy corriendo con 512 subprocesos disponibles
8 requests currently being processed, 504 idle workers
Sin embargo, el intento de 265 solicitudes simultáneas sigue arrojando resultados casi idénticos a los de antes
Connection Times (ms)
min mean[+/-sd] median max
Connect: 25 211 714.7 31 3034
Processing: 17 94 28.6 103 138
Waiting: 17 93 28.5 103 138
Total: 57 306 700.8 138 3071
Percentage of the requests served within a certain time (ms)
50% 138
66% 145
75% 150
80% 161
90% 167
95% 3066
98% 3068
99% 3068
100% 3071 (longest request)
Después de fregar la documentación (y de Intercambio de la Pila) estoy en una pérdida para más opciones de configuración para intentar resolver este cuello de botella. Hay algo que me estoy perdiendo? Debo empezar a buscar respuestas fuera de apache? Ha alguien más visto este comportamiento? Cualquier ayuda sería muy apreciada.
EDITAR:
Como por Ladadadada los consejos, me encontré con strace en contra de apache. He probado con-tt y-T un par de veces, y no podía encontrar nada fuera de lo normal. Luego traté de correr strace-c en contra de la ejecución de todos los procesos de apache, y obtuve esto:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
22.09 0.317836 5 62128 4833 open
19.91 0.286388 4 65374 1896 lstat
13.06 0.187854 0 407433 pread
10.70 0.153862 6 27076 semop
7.88 0.113343 3 38598 poll
6.86 0.098694 1 100954 14380 read
(...abdridged)
Si estoy leyendo este derecho (y tener paciencia conmigo, ya que yo no uso strace muy a menudo) ninguna de las llamadas al sistema pueden tener en cuenta la cantidad de tiempo que estas solicitudes se están tomando. Casi parece como si el cuello de botella se produce antes de las solicitudes, incluso, llegar a los subprocesos de trabajo.
EDIT 2:
Como varias personas sugirieron, me encontré de nuevo la prueba en el servidor web (anteriormente, la prueba se ejecuta a partir de un punto neutro de internet de la ubicación). Los resultados fueron sorprendentes:
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 11 6.6 12 21
Processing: 5 247 971.0 10 4204
Waiting: 3 245 971.3 7 4204
Total: 16 259 973.3 21 4225
Percentage of the requests served within a certain time (ms)
50% 21
66% 23
75% 24
80% 24
90% 26
95% 4225
98% 4225
99% 4225
100% 4225 (longest request)
La parte inferior de la línea de tiempo, es similar a la prueba basada en internet, pero parece que siempre será un poco peor cuando se ejecuta localmente. Más curiosamente, el perfil ha cambiado drásticamente. Mientras que antes la mayor parte de las solicitudes de' tiempo que se gastó en "conectar" ahora el cuello de botella parece estar en el procesamiento o en espera. Yo soy de izquierda a sospechar que en realidad, esto puede ser un tema aparte que anteriormente se estaba enmascarada por la red limitaciones.
Ejecución de la prueba de nuevo desde otra máquina de la misma red local como el host de Apache, estoy viendo mucho más razonable de los resultados:
Connection Times (ms)
min mean[+/-sd] median max
Connect: 1 2 0.8 2 4
Processing: 13 118 99.8 205 222
Waiting: 13 118 99.7 204 222
Total: 15 121 99.7 207 225
Percentage of the requests served within a certain time (ms)
50% 207
66% 219
75% 220
80% 221
90% 222
95% 224
98% 224
99% 225
100% 225 (longest request)
Estas dos pruebas juntas plantear una serie de preguntas, pero, aparte de eso, hay ahora un caso convincente para algún tipo de grave cuello de botella de la red pasando por debajo de cierta cantidad de carga. Creo que los próximos pasos serán la investigación de la capa de red por separado.