Ir al contenido principal

Al CAC se le pide frecuentemente que investigue los problemas con las colas de mensajes de VOS. Aquí hay un par de interesantes, junto con algunas soluciones y recomendaciones que me gustaría compartir con ustedes.

Problema 1: Recientemente, un cliente vino a nosotros con un problema. Un solicitante no pudo añadir un mensaje a la cola de mensajes, recibiendo el código de error e$max_file_excedido. Extrañamente, la cola estaba vacía, como lo muestra el comando list_messages.

Al examinar la cola, se vio que el recuento de bloques de disco utilizados para esta cola se acercaba al tamaño máximo de archivo para un archivo sin extensión.

nombre: %s1#d01>AppData>queue.MQ

organización del fichero: fichero de la cola de mensajes
la última vez que se usó en: 11-08-16 14:45:13 edt
modificado por última vez en: 11-08-16 14:45:13 edt
la última vez que se salvó en: 10-06-14 21:34:18 edt
tiempo creado: 10-06-09 11:03:15 edt
archivo de transacción: sí
tronco protegido: no
interruptor de seguridad: no
auditoría: no
extensión de la dinámica: no
tamaño de la extensión: 1
último mensaje: 51689380
bloques utilizados: 520201

¿Por qué esta cola estaba llena y vacía?

En algún momento del pasado, los servidores responsables de drenar los mensajes de la cola estaban fuera de línea. Esto dio lugar a una gran acumulación de mensajes. Estos mensajes fueron eventualmente manejados por los servidores y eliminados de la cola. Cuando se eliminan mensajes de una cola, se añade una clave al índice _record_index de la cola, y el valor de la clave indica el número de bytes de los mensajes eliminados. Cuando se agrega un nuevo mensaje a una cola de mensajes, el sistema de archivos intentará encontrar un mensaje previamente eliminado del tamaño exacto del nuevo mensaje. Si no hay ninguno disponible, el nuevo mensaje se escribe en el espacio virgen al final de la cola.

En este caso, no había suficiente espacio virgen en la cola para contener el nuevo mensaje, y no había ningún mensaje preexistente borrado del tamaño correcto.

La moraleja de esta historia es que es una buena idea limitar el número de longitudes de mensajes únicos en cualquier cola. En lugar de que cada mensaje utilice el número exacto de bytes que necesita, redondea el valor hasta un tamaño estándar. Utilizando esta técnica, se aumenta la posibilidad de que un nuevo mensaje pueda reutilizar el espacio de un mensaje previamente eliminado.

Problema 2: Recientemente, otra situación surgió en relación con el desempeño de las colas de mensajes. Un cliente declaró que el tiempo para vaciar una cola de mensajes de más de 400.000 mensajes estaba tomando una cantidad desmesurada de tiempo.

Recientemente habían tenido un problema con sus procesos de servidor al no poder procesar los mensajes en una cola de mensajes de manera oportuna. Afortunadamente, los solicitantes se habían mantenido en funcionamiento para que no se perdieran datos. Cuando se resolvió el problema del servidor, pasaron muchas horas antes de que se pusieran al día con las solicitudes atrasadas y pudieran empezar a procesar las transacciones recientes. El cliente se preguntaba por qué había ocurrido esto, y cómo se podía prevenir o acelerar en situaciones futuras.

Cuando se borra un mensaje en una cola de mensajes, se añade una clave al índice _record_index mantenido por el sistema, donde el valor de la clave es la longitud del mensaje. Si el mensaje que se está borrando tiene la misma longitud que un mensaje previamente borrado, la posición de datos no utilizada se guarda como una entrada duplicada en la clave que contiene ese tamaño de mensaje al final de la lista de valores duplicados. Así pues, si hay cientos de miles de mensajes borrados, todos del mismo tamaño (o el conjunto de longitudes de los mensajes borrados es pequeño), la lista de claves duplicadas es muy larga y el tiempo para borrar un solo mensaje aumenta linealmente.

A la inversa, cuando se añade un mensaje a la cola y existe una clave _record_index para la longitud del mensaje, el espacio ocupado por el último registro eliminado se reutiliza para contener los datos del nuevo mensaje. Este valor debe entonces ser eliminado del valor de la clave que contiene la longitud del mensaje. Así pues, el tiempo para añadir un mensaje aumenta linealmente; cuantos más mensajes borrados, más tiempo se tarda en añadir un nuevo mensaje.

La moraleja de esta historia es que los datos mantenidos por el sistema en las colas de mensajes tienen memoria; las colas recuerdan las ubicaciones y tamaños de todos los mensajes anteriores. Esta información persiste incluso después de que la cola se vacía. Intente evitar que las colas de mensajes crezcan hasta un tamaño enorme (decenas o cientos de miles de bloques de disco). De lo contrario, verás que el costo de agregar y eliminar mensajes en una cola puede crecer con el tiempo.

Las soluciones a ambas situaciones son las mismas.

Solución A: Una cola de mensajes puede ser truncada mientras se abre. La rutina s$truncate_queue puede ser usada para lograr esto. Sin embargo, hay 4 condiciones que deben ser satisfechas:

1: no debe haber solicitantes que mantengan la cola de mensajes abierta

2: la cola de mensajes debe ser drenada de todos los mensajes

3: esta rutina debe ser llamada por un servidor

4: la cola no puede ser un archivo de transacción

Si las 3 primeras condiciones no se cumplen, s$truncate_queue devolverá e$no_truncate_queue. Si la última condición no se cumple, s$truncate_queue devolverá e$invalid_io_operación.

Solución B: si el diseño de la aplicación permite tener varios servidores, se puede cambiar periódicamente el nombre de la cola de mensajes existente, crear una nueva cola de mensajes con el nombre correcto, iniciar un nuevo conjunto de servidores y hacer rebotar a los solicitantes. Cuando los servidores se inicien, comenzarán a procesar en una nueva cola de mensajes, pero vacía. Cuando los solicitantes se inicien, agregarán sus solicitudes a la nueva cola de mensajes vacía. El conjunto original de servidores puede permanecer en funcionamiento, procesando la acumulación de solicitudes hasta que la cola esté vacía. Entonces el antiguo conjunto de servidores puede ser detenido, y la antigua cola de mensajes puede ser eliminada.

Además, una solución al problema 1 puede ser utilizar una cola de mensajes basada en la extensión. Eso permitiría colocar mensajes adicionales en la cola, ya que el tamaño máximo del archivo sería mayor por un factor del tamaño de la extensión. Sin embargo, al utilizar colas de mensajes basadas en la extensión, el rendimiento será incluso peor de lo normal si o cuando la cola de mensajes contenga alguna vez un gran número de mensajes en un momento dado.

Como ya se ha mencionado, la limitación del número de longitudes de mensajes únicos en una cola determinada mejorará la probabilidad de que un nuevo mensaje pueda reutilizar el espacio liberado por un mensaje previamente borrado. Esto ayudará a resolver los dos problemas mencionados en este post.