Cloister → gestión simple de clústeres OTP

Prácticamente cada aplicación empresarial exitosa, tarde o temprano, entra en una fase donde se requiere escalado horizontal. En muchos casos, simplemente se puede iniciar una nueva instancia y reducir la carga promedio. Pero hay casos menos triviales en los que debemos asegurarnos de que diferentes nodos se conozcan entre sí y distribuyan la carga de trabajo de manera adecuada.

Cloister → gestión simple de clústeres OTP

Tuvo la suerte de que erlang, que elegimos por su sintaxis amigable y el hype que lo rodea, tiene soporte de primera clase para sistemas distribuidos. En teoría, esto suena totalmente trivial:

La transmisión de mensajes entre procesos en diferentes nodos, así como entre enlaces y monitores, es transparente […]

En la práctica, todo es un poco más complicado. El sistema distribuido erlang fue diseñado cuando 'contenedor' significaba una gran caja de metal para el transporte, y 'docker' era simplemente un sinónimo de estibador portuario. En IP4 había muchas direcciones no utilizadas, los cortes de red generalmente eran causados por ratas que mordían los cables, y el tiempo medio de funcionamiento sin fallos de un sistema de producción se medía en décadas.

Ahora todos somos increíblemente autónomos, empaquetados y ejecutamos un sistema distribuido erlang en un entorno donde las direcciones IP dinámicas se asignan al azar, y los nodos pueden aparecer y desaparecer a voluntad del scheduler. Para evitar un montón de código en cada proyecto que ejecuta un sistema distribuido, se necesita ayuda para enfrentar el entorno hostil. erlang: sé que hay

Notalibcluster . Es realmente genial, tiene más de mil estrellas, el autor es conocido en la comunidad y todo eso. Si estás contento con las maneras que ofrece este paquete para crear y mantener clústeres, me alegra por ti. Yo, lamentablemente, necesito mucho más. Quiero gestionar la configuración en detalle y no ser un espectador externo en el teatro de reconfiguración del clúster.Lo que necesitaba personalmente era una biblioteca que asumiera la gestión del clúster y tuviera las siguientes características:

Requisitos

trabajo transparente tanto con una lista de nodos codificada como con descubrimiento dinámico a través de servicios

  • callback totalmente funcional en cada cambio de topología (un nodo aquí, un nodo allá, inestabilidad de red, particiones); erlang;
  • callback completo en cada cambio de topología (nodo aquí, nodo allá, inestabilidad de la red, divisiones);
  • interfaz transparente para iniciar un clúster con nombres largos y cortos, así como con :nonode@nohost;
  • soporte de Docker desde el principio, sin necesidad de escribir código de infraestructura.

Lo último significa que, después de que he probado la aplicación localmente en :nonode@nohost, o en un entorno artificialmente distribuido utilizando test_cluster_task, quiero simplemente ejecutar docker-compose up --scale my_app=3 y ver cómo ejecuta tres instancias en Docker sin ningún cambio en el código. También quiero que las aplicaciones dependientes, como mnesia — cuando la topología cambia, rehagan el clúster en segundo plano sin ningún empujón adicional por parte de la aplicación.

Cloister no está pensado como una biblioteca capaz de todo: desde soportar clústeres hasta preparar café. No es una bala de plata, que busca abarcar todos los casos posibles, ni ser una solución académicamente completa en el sentido que los teóricos de CS otorgan a este término. Esta biblioteca está destinada a servir un objetivo muy claro, pero ejecutar su no tan gran carga de trabajo de manera perfecta. Este objetivo se centrará en proporcionar total transparencia entre el entorno local de desarrollo y el entorno distribuido de elasticidad, lleno de contenedores hostiles.

El enfoque elegido

Cloister se supone que debe ejecutarse como una aplicación, aunque los usuarios experimentados pueden trabajar con la construcción y mantenimiento del clúster manualmente, lanzando directamente Cloister.Manager en el árbol de supervisores de la aplicación objetivo.

Al ejecutarse como aplicación, la biblioteca depende de config, de donde lee los siguientes valores clave:

config :cloister,
  otp_app: :my_app,
  sentry: :"cloister.local", # o ~w|n1@foo n2@bar|a
  consensus: 3,              # número de nodos a considerar
                             #    el clúster está en funcionamiento
  listener: MyApp.Listener   # oyente que se llamará cuando
                             #    el anillo haya cambiado

Los parámetros anteriores significan literalmente lo siguiente: Cloister se utiliza para la aplicación OTP :my_app, utiliza descubrimiento de servicio erlang para conectar nodos, al menos tres, y MyApp.Listener módulo (que implementa @behaviour Cloister.Listener) configurado para recibir notificaciones sobre cambios en la topología. Una descripción detallada de la configuración completa se puede encontrar en la documentación.

Con esta configuración, la aplicación Cloister tendrán se ejecutará por fases, posponiendo el proceso de inicio de la aplicación principal hasta que se logre consenso (tres nodos conectados y enlazados, como en el ejemplo anterior). Esto le da a la aplicación principal la posibilidad de suponer que cuando se inicie, el clúster ya estará disponible. Con cada cambio en la topología (que serán muchos, ya que los nodos no se inician completamente de manera sincrónica), se invocará un manejador. MyApp.Listener.on_state_change/2. En la mayoría de los casos, realizamos una acción cuando recibimos un mensaje con el estado. %Cloister.Monitor{status: :up}, lo que significa: “hola, el clúster está armado”.

En la mayoría de los casos, establecer consensus: 3 es óptimo, porque incluso si esperamos que se conecten más nodos, la devolución de llamada se realizará a través de status: :rehashing → status: :up en cualquier nuevo nodo agregado o eliminado.

Al iniciar en modo de desarrollo, es suficiente simplemente establecer consensus: 1 y Cloister saltará felizmente la espera del ensamblaje del clúster, al ver :nonode@nohost, o :node@host, o :node@host.domain — dependiendo de cómo se haya configurado el nodo (:none | :shortnames | :longnames).

Gestión de aplicaciones distribuidas

Las aplicaciones distribuidas no existen en un vacío, generalmente incluyen dependencias distribuidas, como mnesia. Es fácil manejar su reconfiguración desde la misma devolución de llamada on_state_change/2. Aquí hay una descripción detallada de cómo reconfigurar mnesia sobre la marcha en la documentación Cloister.

La principal ventaja de usar Cloister es que realiza todas las operaciones necesarias para reconstruir el clúster después de un cambio en la topología. bajo el capó.La aplicación simplemente se inicia en un entorno distribuido ya preparado, con todos los nodos conectados, independientemente de si conocemos las direcciones IP y, por ende, los nombres de los nodos de antemano, o si han sido asignados/cambiados dinámicamente. Esto no requiere ninguna configuración especial de Docker y desde el punto de vista del desarrollador de aplicaciones, no hay diferencia entre ejecutar en un entorno distribuido o en local en. :nonode@nohost. Para más detalles sobre esto, se puede leer en la documentación.

Aunque el manejo complejo de los cambios en la topología es posible a través de una implementación propia, MyApp.Listener, siempre pueden existir casos límite donde estas limitaciones de la biblioteca y el enfoque sesgado hacia la configuración se conviertan en un obstáculo para la implementación. Esto es normal, solo toma lo mencionado anteriormente. . Es realmente genial, tiene más de mil estrellas, el autor es conocido en la comunidad y todo eso. Si estás contento con las maneras que ofrece este paquete para crear y mantener clústeres, me alegra por ti. Yo, lamentablemente, necesito mucho más. Quiero gestionar la configuración en detalle y no ser un espectador externo en el teatro de reconfiguración del clúster., que es más versátil, o incluso manejar un clúster de bajo nivel por su cuenta. El objetivo de esta biblioteca de código no es cubrir todos los posibles escenarios, sino utilizar el escenario más común sin dolor innecesario y copias y pegados engorrosos.

Nota: en este lugar, la frase original era '¡Feliz agrupamiento!', y Yandex, que es la herramienta de traducción que utilizo (no voy a estar buscando en diccionarios), me sugirió '¡Feliz conglomerado!'. Un mejor traducción, quizás, especialmente a la luz de la situación geopolítica actual, es casi inimaginable.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster