2011-12-28 7 views
10

tengo clúster RabbitMQ con dos nodos en la producción y el cluster está rompiendo con estos mensajes de error:clúster RabbitMQ no está reconectando después de fallo de la red

= INFORME ERROR ==== 23-Dec-2011 :: 04:21:34 ===
** nodo de conejo @ rabbitmq02 no responder ** ** Eliminar
(timedout) ** conexión

= INFO INFORME ==== 23-Dic-2011 :: 04 : 21: 35 ===
nodo conejo @ rabbitmq02 perdido 'conejo'

= INFORME DE ERROR ==== 23-Dic-2011 :: 04: 21: 49 ===
Mnesia (rabbit @ rabbitmq01): ** ERROR ** mnesia_event obtuvo {inconsistent_database, running_partitioned_network, rabbit @ rabbitmq02}

traté de simular el problema matando a la conexión entre los dos nodos utilizando "tcpkill", el grupo se ha desconectado, y sorprendentemente los dos nodos no están tratando de volver a conectar!

Cuando el clúster se rompe, el equilibrador de carga haproxy aún marca ambos nodos como activos y envía una solicitud a ambos, aunque no están en un clúster.

Mis preguntas:

  1. Si los nodos están configurados para funcionar como un grupo, cuando llego a un fallo en la red, ¿por qué no están tratando de volver a conectar después?

  2. ¿Cómo puedo identificar el clúster roto y apagar uno de los nodos? Tengo problemas de consistencia cuando trabajo con los dos nodos por separado.

Respuesta

8

Otra forma de recuperarse de este tipo de error es trabajar con Mnesia, que es la base de datos que usa RabbitMQ como mecanismo de persistencia y para la sincronización de las instancias RabbitMQ (y el estado maestro/esclavo). . Para todos los detalles, se refieren a la siguiente URL: http://www.erlang.org/doc/apps/mnesia/Mnesia_chap7.html

añadiendo la sección pertinente aquí:

Hay varias ocasiones cuando Mnesia puede detectar que la red se ha dividido debido a un fallo de comunicación.

Una es cuando Mnesia ya está en funcionamiento y los nodos de Erlang obtienen contacto de nuevo. Entonces Mnesia intentará ponerse en contacto con Mnesia en el otro nodo para ver si también cree que la red ha sido particionada por un tiempo. Si Mnesia en ambos nodos ha registrado las entradas mnesia_down entre sí, Mnesia genera un evento del sistema, llamado {inconsistent_database, running_partitioned_network, Node} que es enviado al manejador de eventos de Mnesia y a otros posibles suscriptores. El controlador de evento predeterminado informa un error al registrador de errores.

En otra ocasión cuando Mnesia puede detectar que la red ha sido particionada debido a una falla de comunicación, está en la puesta en marcha. Si Mnesia detecta que tanto el nodo local como otro nodo recibieron mnesia_down uno del otro, genera un {sistema de base de datos inconsistente, starting_network, Node} y actúa como se describe anteriormente .

Si la aplicación detecta que ha habido un fallo de comunicación que puede haber causado una base de datos incompatibles, puede utilizar el función mnesia: set_master_nodes (Tab, nodos) para determinar a partir del cual nodos cada mesa puede ser cargado.

En algoritmo de carga de la mesa normal del Mnesia de puesta en marcha será anulada y la mesa serán cargados desde uno de los nodos principales definidos para la tabla , independientemente de las entradas potenciales mnesia_down en el registro. Los nodos solo pueden contener nodos donde la tabla tiene una réplica y si está vacío, el mecanismo de recuperación del nodo principal para la tabla particular se reiniciará y el mecanismo de carga normal se utilizará cuando se reinicie el siguiente .

La función mnesia: set_master_nodes (Nodos) establece nodos maestros para todas las tablas . Para cada tabla, determinará sus nodos de réplica e invocará mnesia: set_master_nodes (Tab, TabNodes) con los nodos de réplica que están incluidos en la lista Nodos (es decir, TabNodes es la intersección de los nodos y los nodos de réplica de la tabla). Si la intersección es vacía, el mecanismo de recuperación del nodo principal para la tabla particular será se reiniciará y el mecanismo de carga normal se usará en el siguiente reinicio.

El funciones mnesia: SYSTEM_INFO (master_node_tables) y mnesia: table_info (Tab, master_nodes) se pueden usar para obtener información sobre los posibles nodos maestros.

Determinar qué datos conservar después de una falla de comunicación está fuera del alcance de Mnesia. Un enfoque sería determinar qué "isla" contiene la mayoría de los nodos. El uso de la opción {mayoría, verdadero} para tablas críticas puede ser una forma de garantizar que los nodos que no son parte de una "isla mayoritaria" no puedan actualizar esas tablas. Tenga en cuenta que esto constituye una reducción en el servicio en los nodos minoritarios. Esta sería una compensación a favor de garantías de mayor consistencia.

La función mnesia: force_load_table (Tab) se puede usar para forzar la carga independientemente de qué mecanismo de carga de tabla esté activado.

Esta es una forma más larga y complicada de recuperarse de tales fallos .. pero dará mejor granularidad y control sobre los datos que deben estar disponibles en el nodo maestro final (esto puede reducir la cantidad de pérdida de datos que podría suceder al "fusionar" maestros de RabbitMQ).

9

RabbitMQ Los clústeres no funcionan bien en redes no confiables (parte de la documentación de RabbitMQ). Entonces, cuando ocurre la falla de red (en un clúster de dos nodos), cada nodo piensa que es el maestro y el único nodo en el clúster. Dos nodos maestros no se vuelven a conectar automáticamente porque sus estados no se sincronizan automáticamente (incluso en el caso de un esclavo RabbitMQ, la sincronización real del mensaje no ocurre), el esclavo simplemente "capta" los mensajes que se consumen en la cola y más mensajes ser agregado).

Para detectar si tiene un clúster rota, ejecute el comando:

rabbitmqctl cluster_status 

en cada uno de los nodos que forman parte del clúster. Si el clúster está roto, solo verá un nodo. Algo así como:

Cluster status of node [email protected] ... 
[{nodes,[{disc,[[email protected]]}]},{running_nodes,[[email protected]]}] 
...done. 

En tales casos, tendrá que ejecutar el siguiente conjunto de comandos en uno de los nodos que forman parte del clúster original (de modo que se une a otro nodo maestro (digamos rabbitmq1) en el clúster como esclavo):

rabbitmqctl stop_app 

rabbitmqctl reset 

rabbitmqctl join_cluster [email protected] 

rabbitmqctl start_app 

Por último, compruebe el estado del clúster de nuevo ... esta vez debería ver ambos nodos.

Nota: Si tiene los nodos RabbitMQ en una configuración de HA utilizando una IP virtual (y los clientes se conectan a RabbitMQ usando esta IP virtual), entonces el nodo que debe ser maestro debe ser el que tenga el IP virtual.

+0

¿Es posible configurar los nodos para que DO sincronicen automáticamente sus estados siempre que la red esté disponible nuevamente? –

+1

Que yo sepa (a menos que esto esté disponible en una versión más nueva de RabbitMQ ... no he verificado por lo menos un año). –

6

RabbitMQ también ofrece dos formas de tratar particiones de red automáticamente: modo pausa-minoría y modo de autohealización. (El comportamiento predeterminado se conoce como modo de ignorar).

En modo pausa-minoría, RabbitMQ pausará automáticamente los nodos del clúster que determinan que son minoría (es decir, menos o igual que la mitad del número total de nodos) después de ver que bajan otros nodos. Por lo tanto, elige la tolerancia de partición sobre la disponibilidad del teorema CAP. Esto garantiza que, en el caso de una partición de red, como máximo los nodos de una sola partición continuarán ejecutándose.

En modo autoheal RabbitMQ decidirá automáticamente en una partición ganadora si se considera que se ha producido una partición. Reiniciará todos los nodos que no están en la partición ganadora. La partición ganador es el que tiene la mayoría de particiones de manipulación automática de

clientes conectados (o si esto produce un empate, el que tiene el mayor número de nodos, y si que todavía produce un empate entonces una de las particiones es elegido de una manera no especificada).

Puede habilitar cualquiera de los modos estableciendo el parámetro de configuración cluster_partition_handling para la aplicación de conejo en su archivo de configuración en pause_minority o autoheal.

¿Qué modo debo elegir?

Es importante comprender que permitir que RabbitMQ trabaje con particiones de red automáticamente no las hace menos problemáticas. Las particiones de red siempre causarán problemas para los clústeres RabbitMQ; simplemente obtienes cierto grado de elección sobre qué tipo de problemas obtienes. Como se indicó en la introducción, si desea conectar los clústeres RabbitMQ a través de enlaces generalmente no confiables, debe usar federación o la pala.

Dicho esto, es posible que desee elegir un modo de recuperación de la siguiente manera:

  • ignoran Su red es realmente fiable. Todos sus nodos están en un bastidor, conectados con un interruptor, y ese interruptor también es la ruta al mundo exterior. No desea correr ningún riesgo de que su clúster se apague si falla alguna otra parte (o si tiene un clúster de dos nodos).

  • pause_minority Su red es tal vez menos confiable. Se ha agrupado en 3 AZ en EC2, y supone que solo una AZ fallará a la vez. En ese escenario, desea que los dos AZ restantes continúen funcionando y los nodos de la AZ fallida vuelvan a unirse automáticamente y sin problemas cuando vuelva la AZ.

  • autoheal Su red puede no ser confiable. Le preocupa más la continuidad del servicio que la integridad de los datos. Puede tener un clúster de dos nodos.

Responde la pregunta es de rabbitmq docs. https://www.rabbitmq.com/partitions.html le dará una descripción más detallada.

Cuestiones relacionadas