Ignite Service Grid - Reiniciar

El 26 de febrero, celebramos una reunión de Apache Ignite GreenSource, donde hablaron los contribuyentes del proyecto de código abierto. apache encender. Un hecho importante en la vida de esta comunidad fue la reestructuración del componente. Encender la red de servicio, que le permite implementar microservicios personalizados directamente en un clúster de Ignite. Habló de este difícil proceso en el encuentro. Vyacheslav Daradur, ingeniero de software y colaborador de Apache Ignite durante más de dos años.

Ignite Service Grid - Reiniciar

Comencemos con lo que es Apache Ignite en general. Esta es una base de datos que es un almacenamiento distribuido de clave/valor con soporte para SQL, transaccionalidad y almacenamiento en caché. Además, Ignite le permite implementar servicios personalizados directamente en un clúster de Ignite. El desarrollador tiene acceso a todas las herramientas que proporciona Ignite: estructuras de datos distribuidas, mensajería, streaming, computación y cuadrícula de datos. Por ejemplo, cuando se utiliza Data Grid, el problema de administrar una infraestructura separada para el almacenamiento de datos y, como consecuencia, los gastos generales resultantes desaparecen.

Ignite Service Grid - Reiniciar

Con la API de Service Grid, puede implementar un servicio simplemente especificando el esquema de implementación y, en consecuencia, el servicio en sí en la configuración.

Normalmente, un esquema de implementación es una indicación de la cantidad de instancias que se deben implementar en los nodos del clúster. Hay dos esquemas de implementación típicos. El primero es Cluster Singleton: en cualquier momento dado, se garantiza que una instancia de un servicio de usuario estará disponible en el clúster. El segundo es Node Singleton: se implementa una instancia del servicio en cada nodo del clúster.

Ignite Service Grid - Reiniciar

El usuario también puede especificar la cantidad de instancias de servicio en todo el clúster y definir un predicado para filtrar los nodos adecuados. En este escenario, el propio Service Grid calculará la distribución óptima para implementar servicios.

Además, existe una función llamada Affinity Service. La afinidad es una función que define la relación de las claves con las particiones y la relación de las partes con los nodos en la topología. Con la clave, puede determinar el nodo principal en el que se almacenan los datos. De esta manera puede asociar su propio servicio con una clave y un caché de función de afinidad. Si la función de afinidad cambia, se producirá una redistribución automática. De esta manera, el servicio siempre estará ubicado cerca de los datos que necesita manipular y, en consecuencia, reducirá la sobrecarga de acceso a la información. Este esquema puede denominarse una especie de computación colocada.

Ahora que hemos descubierto cuál es la belleza de Service Grid, hablemos de su historial de desarrollo.

lo que fue antes

La implementación anterior de Service Grid se basó en el caché del sistema replicado transaccional de Ignite. La palabra "caché" en Ignite se refiere al almacenamiento. Es decir, esto no es algo temporal, como podría pensarse. A pesar de que el caché se replica y cada nodo contiene el conjunto de datos completo, dentro del caché tiene una representación particionada. Esto se debe a la optimización del almacenamiento.

Ignite Service Grid - Reiniciar

¿Qué pasó cuando el usuario quiso implementar el servicio?

  • Todos los nodos del clúster se suscribieron para actualizar los datos en el almacenamiento mediante el mecanismo de consulta continua integrado.
  • El nodo iniciador, en una transacción de lectura confirmada, creó un registro en la base de datos que contenía la configuración del servicio, incluida la instancia serializada.
  • Cuando se notificó una nueva entrada, el coordinador calculó la distribución en función de la configuración. El objeto resultante se volvió a escribir en la base de datos.
  • Si un nodo formaba parte de la distribución, el coordinador tenía que implementarlo.

Lo que no nos convenía

En algún momento llegamos a la conclusión: esta no es la forma de trabajar con servicios. Hubo varias razones.

Si se produjo algún error durante la implementación, solo se podrá descubrir en los registros del nodo donde sucedió todo. Solo hubo implementación asincrónica, por lo que después de devolver el control al usuario desde el método de implementación, se necesitó algo de tiempo adicional para iniciar el servicio, y durante este tiempo el usuario no pudo controlar nada. Para seguir desarrollando Service Grid, crear nuevas funciones, atraer nuevos usuarios y hacer la vida de todos más fácil, algo debe cambiar.

Al diseñar el nuevo Service Grid, en primer lugar queríamos ofrecer una garantía de implementación sincrónica: tan pronto como el usuario recuperara el control de la API, podría utilizar los servicios inmediatamente. También quería darle al iniciador la capacidad de manejar errores de implementación.

Además, quería simplificar la implementación, es decir, alejarme de las transacciones y el reequilibrio. A pesar de que el caché se replica y no hay equilibrio, surgieron problemas durante una implementación grande con muchos nodos. Cuando la topología cambia, los nodos necesitan intercambiar información y, en una implementación grande, estos datos pueden pesar mucho.

Cuando la topología era inestable, el coordinador necesitaba recalcular la distribución de servicios. Y, en general, cuando hay que trabajar con transacciones en una topología inestable, esto puede provocar errores difíciles de predecir.

Problemas

¿Qué son los cambios globales sin los problemas que los acompañan? El primero de ellos fue un cambio en la topología. Debe comprender que en cualquier momento, incluso en el momento de la implementación del servicio, un nodo puede entrar o salir del clúster. Además, si en el momento de la implementación el nodo se une al clúster, será necesario transferir constantemente toda la información sobre los servicios al nuevo nodo. Y no estamos hablando sólo de lo que ya se ha desplegado, sino también de los despliegues actuales y futuros.

Este es sólo uno de los problemas que se pueden recopilar en una lista aparte:

  • ¿Cómo implementar servicios configurados estáticamente al inicio del nodo?
  • Salir de un nodo del clúster: ¿qué hacer si el nodo aloja servicios?
  • ¿Qué hacer si el coordinador ha cambiado?
  • ¿Qué hacer si el cliente se vuelve a conectar al clúster?
  • ¿Es necesario procesar las solicitudes de activación/desactivación y cómo?
  • ¿Qué pasaría si pidieran la destrucción del caché y tuviéramos servicios de afinidad vinculados a ello?

Y eso no es todo.

Solución

Como objetivo, elegimos el enfoque Event Driven con la implementación de la comunicación de procesos mediante mensajes. Ignite ya implementa dos componentes que permiten a los nodos reenviar mensajes entre ellos: comunicación-spi y descubrimiento-spi.

Ignite Service Grid - Reiniciar

Communication-spi permite que los nodos se comuniquen directamente y reenvíen mensajes. Es muy adecuado para enviar grandes cantidades de datos. Discovery-spi le permite enviar un mensaje a todos los nodos del clúster. En la implementación estándar, esto se hace mediante una topología en anillo. También hay integración con Zookeeper, en este caso se utiliza una topología en estrella. Otro punto importante que vale la pena señalar es que Discovery-spi ofrece garantías de que el mensaje definitivamente se entregará en el orden correcto a todos los nodos.

Veamos el protocolo de implementación. Todas las solicitudes de implementación y anulación de la implementación de los usuarios se envían a través de discovery-spi. Esto da lo siguiente garantías:

  • La solicitud será recibida por todos los nodos del clúster. Esto permitirá que la solicitud continúe procesándose cuando cambie el coordinador. Esto también significa que en un mensaje, cada nodo tendrá todos los metadatos necesarios, como la configuración del servicio y su instancia serializada.
  • El orden estricto de la entrega de mensajes ayuda a resolver conflictos de configuración y solicitudes en competencia.
  • Dado que la entrada del nodo en la topología también se procesa mediante descubrimiento-spi, el nuevo nodo recibirá todos los datos necesarios para trabajar con los servicios.

Cuando se recibe una solicitud, los nodos del clúster la validan y crean tareas de procesamiento. Estas tareas se ponen en cola y luego un trabajador independiente las procesa en otro subproceso. Se implementa de esta manera porque la implementación puede llevar una cantidad significativa de tiempo y retrasar intolerablemente el costoso flujo de descubrimiento.

Todas las solicitudes de la cola son procesadas por el administrador de implementación. Tiene un trabajador especial que extrae una tarea de esta cola y la inicializa para comenzar la implementación. Después de esto, ocurren las siguientes acciones:

  1. Cada nodo calcula de forma independiente la distribución gracias a una nueva función de asignación determinista.
  2. Los nodos generan un mensaje con los resultados del despliegue y lo envían al coordinador.
  3. El coordinador agrega todos los mensajes y genera el resultado de todo el proceso de implementación, que se envía mediante descubrimiento-spi a todos los nodos del clúster.
  4. Cuando se recibe el resultado, finaliza el proceso de implementación, tras lo cual la tarea se elimina de la cola.

Ignite Service Grid - Reiniciar
Nuevo diseño basado en eventos: org.apache.ignite.internal.processors.service.IgniteServiceProcessor.java

Si se produce un error durante la implementación, el nodo incluye inmediatamente este error en un mensaje que envía al coordinador. Después de la agregación de mensajes, el coordinador tendrá información sobre todos los errores durante la implementación y enviará este mensaje a través de discovery-spi. La información de error estará disponible en cualquier nodo del clúster.

Todos los eventos importantes en Service Grid se procesan utilizando este algoritmo operativo. Por ejemplo, cambiar la topología también es un mensaje a través de descubrimiento-spi. Y en general, en comparación con lo anterior, el protocolo resultó ser bastante ligero y confiable. Suficiente para manejar cualquier situación durante el despliegue.

¿Qué pasará después?

Ahora sobre los planes. Cualquier cambio importante en el proyecto Ignite se completa como una iniciativa de mejora de Ignite, denominada IEP. El rediseño de Service Grid también tiene un IEP: PEI #17 con el título burlón “Cambio de aceite en la red de servicios”. Pero en realidad no cambiamos el aceite del motor, sino todo el motor.

Dividimos las tareas del IEP en 2 fases. La primera es una fase importante, que consiste en reelaborar el protocolo de implementación. Ya está incluido en el master, puedes probar el nuevo Service Grid, que aparecerá en la versión 2.8. La segunda fase incluye muchas otras tareas:

  • Redistribución en caliente
  • Versionado del servicio
  • Mayor tolerancia a fallos
  • Cliente ligero
  • Herramientas para monitorear y calcular diversas métricas.

Finalmente, podemos asesorarlo sobre Service Grid para construir sistemas de alta disponibilidad y tolerantes a fallas. También te invitamos a visitarnos en lista de desarrolladores и Lista de usuarios Comparte tu experiencia. Su experiencia es realmente importante para la comunidad; le ayudará a comprender hacia dónde avanzar y cómo desarrollar el componente en el futuro.

Fuente: habr.com

Añadir un comentario