12. Performance/Tuning

12.1. Balance con varios servidores

Normalmente los sitios que reciben una gran cantidad de email tienen una configuración tipo "switch" como la que se comentó anteriormente en la sección "Organización con divisiones administrativas". En ese caso puede ser conveniente configurar varios computadores para que reciban la carga de mensajes entrantes y la redirijan a los computadores departamentales.

A fin de lograr esto, se suele aplicar dos técnicas, a saber, vía DNS o mediante NAT. En el DNS es posible especificar varios servidores de switch para la organización con la misma preferencia. Siguiendo el ejemplo de la sección señalada, habría que modificar esto:

; archivo de zona de inkacoca.org
@		IN	MX	10	switch
switch		IN	A		18.1.3.41
lima 		IN	MX	10	lima-mail
lima-mail	IN	A		18.1.3.40
...
Por lo siguiente:
; archivo de zona de inkacoca.org
@		IN	MX	10	switch
switch		IN	A		18.1.3.41
switch		IN	A		18.1.3.42
switch		IN	A		18.1.3.43
lima 		IN	MX	10	lima-mail
lima-mail	IN	A		18.1.3.40
...
Esto supone disponer de tres mailservers llamados "switch" asociados a las direcciones IP 18.1.3.4[123]. Bajo condiciones normales, esto balanceará la carga entre los tres servidores. Para más información, revise la referencia [2] en lo referente a "Round Robin Load Distribution".

El método NAT consistiría en nuestro ejemplo en redirigir las conexiones destinadas a la dirección 18.1.3.41 (no habría ningún cambio en el DNS) hacia un grupo de otras direcciones (DNAT) que realmente están asociadas a los servidores de email. Los ruteadores normalmente disponen de estas facilidades (y por supuesto Linux cuando actúa como router, usando el comando iptables.) No lo explicaremos aquí.

12.2. Intervalo de Queue Run

En sitios pequeños el intervalo debe ser corto a fin de asegurar el rápido envío (por ejemplo, 15 minutos.) En la mayoría de sitios, sin embargo, una hora es un tiempo aceptable.

Como se indicó, el intervalo de Queue Run se especifica mediante opciones al ejecutarse sendmail (opción -q).

12.3. Procesos de ejecución en Queue Run

Cuando el intervalo de Queue Run es corto, cuando los mensajes encolados son muchos, y cuando los servidores remotos son lentos, Sendmail puede lanzar muchos procesos "queue runners" concurrentes que intentan en paralelo limpiar la cola. Esto normalmente debe autocontrolarse, pero en situaciones extremas el número de "queue runners" puede ser muy elevado al punto de crear un peligro para el sistema.

La opción MaxQueueChildren permite especificar el máximo número de procesos "hijos" de Sendmail encargados de procesar la cola simultáneamente. Normalmente no hay límite.

El valor más adecuado se debe obtener observando el comportamiento "usual" de los queue runners de Sendmail, por ejemplo, mediante un comando como el que se muestra:

[root@edithpiaf root]# ps ax | grep sendmail | grep queue | wc -l
	7
Esto se debe observar a distintas horas. Un valor razonable puede ser el máximo observado durante la semana multiplicado por dos.

Por otro lado, si el sistema constantemente tiene problemas de falta de memoria, y se sospecha que el problema está asociado a un número elevado de "queue runners", puede ser conveniente reducir esta opción gradualmente (quizá reduciendo 10% al valor observado) a fin de aliviar este problema. Esto ocasionará que algunos mensajes encolados tarden más en procesarse.

12.4. Limpiar más aprisa los mensajes en cola

La opción "Timeout.queuewarn" determina el lapso que permanece un mensaje en cola para generar un mensaje de alerta al redactor del mismo. Esta alerta le permite saber que el mensaje no pudo ser enviado (default=4 horas.)

La opción "Timeout.queuereturn" determina el tiempo máximo que el sistema mantendrá el mensaje en la cola (intentando enviarlo.) Cuando este tiempo se cumple, el mensaje es eliminado de la cola y se envía una alerta al redactor (default=5 días.)

Por consistencia, Timeout.queuewarn < Timeout.queuereturn.

A fin de que los mensajes "reboten" más aprisa (y la cola se libere más aprisa), es conveniente en ciertos casos reducir estos valores, por ejemplo:

En el archivo "cf":

O Timeout.queuewarn=2h
O Timeout.queuereturn=1d
En M4:
define(`confTO_QUEUEWARN',`2h')
define(`confTO_QUEUERETURN',`1d')

12.5. Cola con varios directorios

El acceso a disco generado por las colas puede ser considerable en sistemas grandes. Una forma de balancear esta carga y mejorar la performance consiste en utilizar discos físicos distintos, los cuales pueden montarse y usarse simultáneamente para la cola.

Esto se puede consiguir creando varios subdirectorios a partir de un directorio principal (por ejemplo bajo /var/spool/mqueue) y configurándolos en el archivo "cf" (o vía M4.)

[root@edithpiaf mqueue]# ls -ld /var/spool/mqueue/
drwx------    2 root     mail         4096 oct  5 13:39 /var/spool/mqueue/
[root@edithpiaf mqueue]# cd /var/spool/mqueue
[root@edithpiaf mqueue]# mkdir cola1
[root@edithpiaf mqueue]# mkdir cola2
[root@edithpiaf mqueue]# mkdir cola3
[root@edithpiaf mqueue]# chmod 700 cola*
[root@edithpiaf mqueue]# mount /dev/sdX cola1
[root@edithpiaf mqueue]# mount /dev/sdY cola2
[root@edithpiaf mqueue]# mount /dev/sdZ cola3
[root@edithpiaf mqueue]# chown root.mail cola*
[root@edithpiaf mqueue]# ls -l
total 12
drwx------    2 root     mail         4096 oct 11 13:01 cola1
drwx------    2 root     mail         4096 oct 11 13:01 cola2
drwx------    2 root     mail         4096 oct 11 13:01 cola3
En el archivo "cf" se colocaría:
QueueDirectory=/var/spool/mqueue/cola*
Por el método M4:
define(`QUEUE_DIR',`/var/spool/mqueue/cola*')
Tenga cuidado de no especificar "/var/spool/mqueue/*" pues esto haría que Sendmail incluya (incorrectamente) los directorios "/var/spool/mqueue/." y "/var/spool/mqueue/..".

12.6. Encolar si hay mucha carga

Si la carga del sistema se hace muy elevada, es conveniente limitar la operación de Sendmail, al menos para los mensajes de menor prioridad.

Cuando un nuevo mensaje es recibido, Sendmail le calcula su prioridad inicial "PRI" con la fórmula señalada anteriormente.

Si la carga es muy elevada, Sendmail tiene la opción de no intentar enviar el mensaje, sino, simplemente encolarlo para un intento posterior. Esto ocurrirá si se verifican las siguientes condiciones:

1) La carga promedio del sistema (load average) es mayor que el indicado en la opción configurable "QueueLA" (cuyo default es ocho.) La carga promedio es un valor proporcionado por el sistema operativo que se puede obtener con el comando "uptime".

2) Se verifica la ecuación:

PRI > QueueFactor /(LA-QueueLA+1)
Recordar que un valor "PRI" más elevado es menor prioridad y por tanto hace más probable que la ecuación anterior se verifique.

QueueFactor es una opción configurable cuyo valor por omisión es 600000.

En sistemas grandes puede ser necesario elevar el valor de QueueLA:

O QueueLA=15
En M4:
define(`confQUEUE_LA',`15')

12.7. Rechazar si hay mucha carga

La opción "RefuseLA" permite especificar un límite para la carga promedio del sistema (load average) a partir del cual Sendmail simplemente rechaza los mensajes que se le envían. Esto, evidentemente asume que quien se está intentando conectar lo intentará nuevamente más adelante.

El valor por omisión de esta opción es doce. En sistemas grandes puede ser necesario elevar este valor.

O RefuseLA=18
En M4:
define(`confREFUSE_LA',`18')

12.8. Procesar lentamente las conexiones

La opción ConnectionRateThrottle permite "relentizar" las conexiones que llegan a un ritmo muy veloz. Por ejemplo, si este parámetro es igual a cinco, en caso de llegar más de cinco conexiones en menos de un segundo, sólo las cinco son atendias inmediatamente. Otras cinco serán atendidas luego de un segundo, y así sucesivamente.

Esta opción es adecuada cuando se usan las opciones QueueLA y RefuseLA.

O ConnectionRateThrottle=5
En M4:
define(`confCONNECTION_RATE_THROTTLE',`5')