Federico Budassi
2012-01-10 00:41:15 UTC
Gente,
después de unos cuatro años sin postear en esta lista en particular, vuelvo
a hacerlo con un problema que me tiene a mal traer.
Esta es la situación, para mi tesis de grado, investigando acerca de Event
Driven Web Servers, intento sacar una comparativa de cantidad máxima de
conexiones keep alive atendidas por distintos Http servers. En particular,
estoy intentando generar la mayor cantidad de conexiones keep-alive con
Apache 2.2.20, corriendo en un Ubuntu Server x64 11.10 virtualizado en un
Vmware (que corre sobre otro Ubuntu Desktop x64 11.04). Qué significa esto?
que con un benchmark (programado por mi en Java, por no servir
ApacheBenchmark, ni httpref, ni JMeter entre otros) genero miles de
requests GET hacia ese Apache y las dejo abiertas, viendo cual es el límite
al que puedo llegar con los 8GB de memoria que tengo asignados a esa
máquina virtual. Obviamente el benchmark no genera esas conexiones
generando un thread por cada una, sino que las genera por medio de un
framework que maneja eventos (Netty), y por lo tanto solo necesita un par
de docenas de threads para generar algo asi como 500000 conexiones con
otros 8GB de ram en otra máquina virtual.
La cuestión es que Apache, con su módulo de multiprocesamiento Worker
(mpm_worker_module), el que trae por defecto en ubuntu, genera un hilo por
cada conexión (situación que es querida por mi en este caso, para probar el
límite de conexiones al cual puedo llegar con la memoria antes dicha).
Ahora, llegado cierto punto, el sistema operativo no le permite a apache
seguir generando hilos, y en /var/log/apache2/errors.log, apache comienza a
quejarse con logs como este:
[Sun Jan 08 22:00:32 2012] [alert] (11)Resource temporarily unavailable:
apr_thread_create: unable to create worker thread
Lo cual deja casi obvio que el kernel le está impidiendo seguir abriendo
threads.
Acá van algunas configuraciones que he estado teniendo que realizar para
lograr agrandar otros límites (antes solo podía llegar a ~32000 conexiones):
- /etc/security/limits.conf (ayuda para cambiar algunos límites visibles
con ulimit que impedían crear más procesos entre otras cosas):
* soft nofile 1000000
* hard nofile 1000000
* soft stack 1024
* hard stack 1024
* soft nproc 1000000
* hard nproc 1000000
* soft sigpending 1000000
* hard sigpending 1000000
- /etc/apache2/apache2.conf
Timeout 86400
KeepAlive On
MaxKeepAliveRequests 0
KeepAliveTimeout 86400
<IfModule mpm_worker_module>
ServerLimit 100
StartServers 30
MinSpareThreads 70000
MaxSpareThreads 90000
ThreadLimit 4000
ThreadsPerChild 4000
ThreadStackSize 262144
MaxClients 200000
MaxRequestsPerChild 0
</IfModule>
- Otras configuraciones y comandos (la primera linea genera varios alias
a una interfaz para tener más de 65530 puertos y poder atender muchas más
conexiones):
for i in `seq 20 35`; do ifconfig eth0:$i 192.168.1.$i up ; done
echo "1024 65535" > /proc/sys/net/ipv4/ip_local_port_range
swapoff -a
sysctl vm.max_map_count=1000000
sysctl kernel.threads-max=1000000
sysctl kernel.pid_max=1000000
En todo lo anterior pueden ver modificaciones a límites del sistema
operativo, una parte de la configuración de apache (la parte que importa),
y algunos comandos que corro cada vez que arranco el sistema para
incrementar límites o crear muchos aliases para una misma interfaces para
poder recibir más de 65536 conexiones por interfaz.
Las conexiones que se generan son simples peticiones estáticas del
index.html con HTTP/1.1 con el header Connection: keep-alive, de tal forma
que las conexiones queden abiertas (y como hay un timeout de 1 día, o 86400
segundos, no se cierran).
La cuestión es simple, como podrán ver, la configuración del worker_mpm de
apache acepta un máximo de 200000 conexiones, y abre al arranque 70000
conexiones, aunque debido a alguna limitación del kernel que estoy pasando
por algo, o que no conozco, apache no es capaz de crear más de
aproximadamente 60000 conexiones (o hilos, dicho de otra forma). Necesito
al menos duplicar ese valor para poder llenar la memoria de mi computadora
de conexiones.
Espero que todo esto se haya entendido bien y comprendan mi punto, si no se
entiende, pregunten.
Muchas gracias por su ayuda, la cual sera muy bien recibida!
Federico Budassi.
después de unos cuatro años sin postear en esta lista en particular, vuelvo
a hacerlo con un problema que me tiene a mal traer.
Esta es la situación, para mi tesis de grado, investigando acerca de Event
Driven Web Servers, intento sacar una comparativa de cantidad máxima de
conexiones keep alive atendidas por distintos Http servers. En particular,
estoy intentando generar la mayor cantidad de conexiones keep-alive con
Apache 2.2.20, corriendo en un Ubuntu Server x64 11.10 virtualizado en un
Vmware (que corre sobre otro Ubuntu Desktop x64 11.04). Qué significa esto?
que con un benchmark (programado por mi en Java, por no servir
ApacheBenchmark, ni httpref, ni JMeter entre otros) genero miles de
requests GET hacia ese Apache y las dejo abiertas, viendo cual es el límite
al que puedo llegar con los 8GB de memoria que tengo asignados a esa
máquina virtual. Obviamente el benchmark no genera esas conexiones
generando un thread por cada una, sino que las genera por medio de un
framework que maneja eventos (Netty), y por lo tanto solo necesita un par
de docenas de threads para generar algo asi como 500000 conexiones con
otros 8GB de ram en otra máquina virtual.
La cuestión es que Apache, con su módulo de multiprocesamiento Worker
(mpm_worker_module), el que trae por defecto en ubuntu, genera un hilo por
cada conexión (situación que es querida por mi en este caso, para probar el
límite de conexiones al cual puedo llegar con la memoria antes dicha).
Ahora, llegado cierto punto, el sistema operativo no le permite a apache
seguir generando hilos, y en /var/log/apache2/errors.log, apache comienza a
quejarse con logs como este:
[Sun Jan 08 22:00:32 2012] [alert] (11)Resource temporarily unavailable:
apr_thread_create: unable to create worker thread
Lo cual deja casi obvio que el kernel le está impidiendo seguir abriendo
threads.
Acá van algunas configuraciones que he estado teniendo que realizar para
lograr agrandar otros límites (antes solo podía llegar a ~32000 conexiones):
- /etc/security/limits.conf (ayuda para cambiar algunos límites visibles
con ulimit que impedían crear más procesos entre otras cosas):
* soft nofile 1000000
* hard nofile 1000000
* soft stack 1024
* hard stack 1024
* soft nproc 1000000
* hard nproc 1000000
* soft sigpending 1000000
* hard sigpending 1000000
- /etc/apache2/apache2.conf
Timeout 86400
KeepAlive On
MaxKeepAliveRequests 0
KeepAliveTimeout 86400
<IfModule mpm_worker_module>
ServerLimit 100
StartServers 30
MinSpareThreads 70000
MaxSpareThreads 90000
ThreadLimit 4000
ThreadsPerChild 4000
ThreadStackSize 262144
MaxClients 200000
MaxRequestsPerChild 0
</IfModule>
- Otras configuraciones y comandos (la primera linea genera varios alias
a una interfaz para tener más de 65530 puertos y poder atender muchas más
conexiones):
for i in `seq 20 35`; do ifconfig eth0:$i 192.168.1.$i up ; done
echo "1024 65535" > /proc/sys/net/ipv4/ip_local_port_range
swapoff -a
sysctl vm.max_map_count=1000000
sysctl kernel.threads-max=1000000
sysctl kernel.pid_max=1000000
En todo lo anterior pueden ver modificaciones a límites del sistema
operativo, una parte de la configuración de apache (la parte que importa),
y algunos comandos que corro cada vez que arranco el sistema para
incrementar límites o crear muchos aliases para una misma interfaces para
poder recibir más de 65536 conexiones por interfaz.
Las conexiones que se generan son simples peticiones estáticas del
index.html con HTTP/1.1 con el header Connection: keep-alive, de tal forma
que las conexiones queden abiertas (y como hay un timeout de 1 día, o 86400
segundos, no se cierran).
La cuestión es simple, como podrán ver, la configuración del worker_mpm de
apache acepta un máximo de 200000 conexiones, y abre al arranque 70000
conexiones, aunque debido a alguna limitación del kernel que estoy pasando
por algo, o que no conozco, apache no es capaz de crear más de
aproximadamente 60000 conexiones (o hilos, dicho de otra forma). Necesito
al menos duplicar ese valor para poder llenar la memoria de mi computadora
de conexiones.
Espero que todo esto se haya entendido bien y comprendan mi punto, si no se
entiende, pregunten.
Muchas gracias por su ayuda, la cual sera muy bien recibida!
Federico Budassi.