Saltar al contenido

El clúster RabbitMQ no se vuelve a conectar después de una falla en la red

No olvides que en la informática un problema casi siempere puede tener más de una soluciones, pero compartimos lo más óptimo y mejor.

Solución:

Los clústeres de RabbitMQ no funcionan bien en redes poco fiables (parte de la documentación de RabbitMQ). Entonces, cuando ocurre la falla de la 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 de mensajes real no ocurre, el esclavo simplemente “se pone al día” cuando los mensajes se consumen de la cola y más mensajes ser agregado).

Para detectar si tiene un clúster roto, 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 como:

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

En tales casos, deberá ejecutar el siguiente conjunto de comandos en uno de los nodos que formaban parte del clúster original (para que se una al otro nodo maestro (por ejemplo, rabbitmq1) en el clúster como esclavo):

rabbitmqctl stop_app

rabbitmqctl reset

rabbitmqctl join_cluster [email protected]

rabbitmqctl start_app

Por último, vuelva a comprobar el estado del clúster … esta vez debería ver ambos nodos.

Nota: Si tiene los nodos RabbitMQ en una configuración HA usando una IP virtual (y los clientes se están conectando a RabbitMQ usando esta IP virtual), entonces el nodo que debe convertirse en maestro debe ser el que tiene la IP virtual.

De RabbitMQ doc: Clustering y particiones de red

RabbitMQ también tiene tres formas de lidiar con las particiones de red automáticamente: pause-minority modo, pause-if-all-down modo y autoheal modo. El comportamiento predeterminado se conoce como ignore modo.

En el modo de pausa-minoritario, RabbitMQ pausará automáticamente los nodos del clúster que determinen que están en minoría (es decir, menos o igual a la mitad del número total de nodos) después de ver que otros nodos caen. Por lo tanto, elige la tolerancia de partición sobre la disponibilidad del teorema de CAP. Esto asegura que en el caso de una partición de red, como máximo los nodos en una sola partición continuarán ejecutándose. Los nodos minoritarios se detendrán tan pronto como se inicie una partición, y comenzarán de nuevo cuando finalice la partición. Esta configuración evita el cerebro dividido y, por lo tanto, puede recuperarse automáticamente de las particiones de red sin inconsistencias.

En el modo de pausa si todo está abajo, RabbitMQ pausará automáticamente los nodos del clúster que no pueden llegar a ninguno de los nodos enumerados. En otras palabras, todos los nodos enumerados deben estar inactivos para que RabbitMQ pause un nodo de clúster. Esto está cerca del modo de pausa-minoritario, sin embargo, permite al administrador decidir qué nodos preferir, en lugar de depender del contexto. Por ejemplo, si el clúster está formado por dos nodos en el bastidor A y dos nodos en el bastidor B, y se pierde el enlace entre los bastidores, el modo de pausa-minoritario pausará todos los nodos. En el modo de pausa si todo está abajo, si el administrador enumeró los dos nodos en el bastidor A, solo los nodos del bastidor B se detendrán. Tenga en cuenta que es posible que los nodos enumerados se dividan en ambos lados de una partición: en esta situación, ningún nodo se detendrá. Es por eso que hay un adicional ignorar/autocuración argumento para indicar cómo recuperarse de la partición.

En el modo de reparación automática, RabbitMQ decidirá automáticamente sobre una partición ganadora si se considera que ha ocurrido una partición, y reiniciará todos los nodos que no estén en la partición ganadora. A diferencia del modo pause_minority, por lo tanto, surte efecto cuando finaliza una partición, en lugar de cuando se inicia.

La partición ganadora es la que tiene más clientes conectados (o si esto produce un empate, la que tiene más nodos; y si eso todavía produce un empate, se elige una de las particiones de una manera no especificada).

Puede habilitar cualquiera de los modos configurando el parámetro de configuración cluster_partition_handling Para el rabbit aplicación en el archivo de configuración para:

  • autoheal
  • pause_minority
  • pause_if_all_down

Si usa el pause_if_all_down modo, se requieren parámetros adicionales:

  • nodes: nodos que no deberían estar disponibles para pausar
  • recover: acción de recuperación, puede ser ignore o autoheal

¿Qué modo elegir?

Es importante comprender que permitir que RabbitMQ se ocupe de las particiones de red automáticamente conlleva compensaciones.

Como se indicó en la introducción, para conectar clústeres de RabbitMQ a través de enlaces generalmente poco confiables, prefiera Federation o Shovel.

Dicho esto, aquí hay algunas pautas para ayudar al operador a determinar qué modo puede ser apropiado o no:

  • ignore: utilícelo cuando la confiabilidad de la red sea la más alta posible en la práctica y la disponibilidad del nodo sea de suma importancia. Por ejemplo, todos los nodos del clúster pueden estar en el mismo bastidor o equivalente, conectados con un conmutador, y ese conmutador también es la ruta al mundo exterior.
  • pause_minority: apropiado cuando se agrupan en racks o zonas de disponibilidad en una sola región, y la probabilidad de perder la mayoría de los nodos (zonas) a la vez se considera muy baja. Este modo intercambia cierta disponibilidad por la capacidad de recuperarse automáticamente si / cuando los nodos perdidos regresan.
  • autoheal: apropiado cuando están más preocupados por la continuidad del servicio que por la coherencia de los datos entre los nodos.

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

Añadiendo la sección relevante aquí:

Hay varias ocasiones en las que 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 vuelven a ponerse en contacto. Luego, Mnesia intentará contactar a Mnesia en el otro nodo para ver si también cree que la red ha estado particionada por un tiempo. Si Mnesia en ambos nodos ha registrado entradas mnesia_down entre sí, Mnesia genera un evento del sistema, llamado inconsistent_database, running_partitioned_network, Node que se envía al controlador de eventos de Mnesia y otros posibles suscriptores. El controlador de eventos predeterminado informa de un error al registrador de errores.

Otra ocasión en la que Mnesia puede detectar que la red se ha dividido debido a un fallo de comunicación es durante el inicio. Si Mnesia detecta que tanto el nodo local como otro nodo recibieron mnesia_down entre sí, genera un evento del sistema inconsistent_database, starts_partitioned_network, Node y actúa como se describe anteriormente.

Si la aplicación detecta que ha habido una falla de comunicación que puede haber causado una base de datos inconsistente, puede usar la función mnesia: set_master_nodes (Tab, Nodos) para identificar desde qué nodos se puede cargar cada tabla.

En el inicio, el algoritmo de carga de la tabla normal de Mnesia se omitirá y la tabla se cargará desde uno de los nodos maestros definidos para la tabla, independientemente de las posibles entradas mnesia_down en el registro. Los nodos solo pueden contener nodos donde la tabla tiene una réplica y, si está vacía, el mecanismo de recuperación del nodo maestro para la tabla en particular se restablecerá y el mecanismo de carga normal se utilizará la próxima vez que se reinicie.

La función mnesia: set_master_nodes (Nodes) establece los 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 de nodos (es decir, TabNodes es la intersección de los nodos y los nodos de réplica de la tabla). Si la intersección está vacía, el mecanismo de recuperación del nodo maestro para la mesa en particular se restablecerá y el mecanismo de carga normal se utilizará en el próximo reinicio.

Las funciones mnesia: system_info (master_node_tables) y mnesia: table_info (Tab, master_nodes) se pueden utilizar para obtener información sobre los nodos maestros potenciales.

Determinar qué datos conservar después de una falla en la comunicación está fuera del alcance de Mnesia. Un enfoque sería determinar qué “isla” contiene la mayoría de los nodos. Usando la mayoría,true para las tablas críticas puede ser una forma de garantizar que los nodos que no forman parte de una “isla mayoritaria” no puedan actualizar esas tablas. Tenga en cuenta que esto constituye una reducción del servicio en los nodos minoritarios. Esta sería una compensación a favor de mayores garantías de coherencia.

La función mnesia: force_load_table (Tab) puede usarse para forzar la carga de la mesa independientemente del mecanismo de carga de la mesa que esté activado.

Esta es una forma más extensa y complicada de recuperarse de tales fallas … pero brindará una mejor granularidad y control sobre los datos que deberían estar disponibles en el nodo maestro final (esto puede reducir la cantidad de pérdida de datos que podría ocurrir al “fusionar” RabbitMQ maestros).

Te invitamos a proteger nuestro cometido ejecutando un comentario o dejando una puntuación te estamos eternamente agradecidos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *