Implementación de un servicio distribuido de n-Productores / 1-Consumidor para el sistema de misión crítica

Aug 17 2020

Estoy tratando de implementar una versión distribuida de multi-productor / 1-consumidor para un sistema de misión crítica. Estoy buscando buenas alternativas al enfoque actual basado en RDBMS.

El problema

El sistema consta de varios (50+) productores que producen continuamente miles de instancias por segundo. Cada instancia es una estructura plana, bien definida y con marca de tiempo. Los productores almacenan cada instancia en una única cola.

En el otro lado, tengo un consumidor que consume las instancias en forma FIFO.

Los productores y el consumidor se ejecutan en diferentes máquinas conectadas por una red privada TCP / IP.

En aras de la integridad, hay dos requisitos estrictos

  1. El consumidor no puede consumir el mismo recurso dos veces. Es un error.
  2. Cada recurso debe ser consumido por el consumidor. Si se pierde un recurso, es una pérdida

Además, la solución debe ejecutarse en servidores Linux y Windows.

Enfoque actual

En la versión actual, el sistema implementa esta solución utilizando una base de datos relacional como bus de datos.

Hay un servidor de base de datos que admite a todos los productores y al consumidor. Los productores insertan recursos en una tabla determinada y el consumidor consume los recursos de esa tabla como se representa en la imagen de arriba.

El modelo de transacción del servidor de base de datos / JDBC permite controlar las inserciones / eliminaciones para evitar la corrupción de la cola.

Ese enfoque actual funciona bien pero:

  1. Introduce la sobrecarga de mantener un servidor de base de datos relacional completo para una tarea donde no se requiere una relación de datos;
  2. El servidor de base de datos relacional debe ajustarse a los requisitos de misión crítica, lo que es difícil de lograr en algunas configuraciones reales cuando la instancia del servidor de base de datos no está dedicada

Alternativas

Aquí enumero algunas alternativas al enfoque actual del bus de datos del servidor de bases de datos relacionales:

Servidor de base de datos relacional ligero dedicado

Este parece ser el enfoque más sencillo: utilizar un servidor de base de datos relacional ligero dedicado como HSQLDB, Apache Derby o H2.

Pros

Tienen una sobrecarga considerablemente menor que mantener en comparación con un RDBMS como MS SQL Server, Oracle DB Server o incluso MySQL. Además, se requieren menos cambios de código y pruebas ya que son básicamente motores SQL como los que se usan en la solución actual.

Contras

Son servidores de bases de datos relacionales, por lo que resulta que todavía existe algún nivel de sobrecarga para realizar una tarea sin relaciones. Otro punto es el aspecto de la misión crítica. Usamos Derby DB internamente durante años para la supervisión del sistema en tiempo real tanto en modo integrado como en red. Funciona muy bien, no se bloquea ni se dañan los datos. Sin embargo, el volumen de transacciones por segundo para ese nuevo uso es mayor.

Servidor Redis

A primera vista, Redis parece perfecto para este caso de uso. En memoria, rápido, sin exceso de relación de datos, sencillo. Ampliamente utilizado como bus de datos y reportado como confiable. Pero no para Windows. Como se dice en los documentos, no se recomienda Redis en Windows . El puerto de Microsoft Windows ya no se mantiene , la última fecha de lanzamiento es 2016, por lo que adjuntar Redis al sistema no parece prometedor.

Implementando una solución desde cero

En últimas palabras, es un problema productor-consumidor. Implementar un servicio de red usando TCP o algo más elegante como Camel y usar una cola concurrente internamente más algún motor de persistencia local será costoso en tiempo, reinventar la rueda, pero sigue siendo una opción.

Estas son las alternativas que estamos considerando hasta ahora. Agradezco que alguien me pueda dar alguna información o recomendación.

Respuestas

2 LieRyan Aug 18 2020 at 02:08

Parece que está buscando una cola de mensajes. Dependiendo de su pila tecnológica, existen varias implementaciones de cola distribuida que pueden interesarle, por ejemplo, ZeroMQ o RabbitMQ.

Algunos enfoques como ZeroMQ pueden ejecutarse sin tener un intermediario de mensajes, lo que significa que los productores y consumidores hablan directamente sin necesidad de otro servicio o una base de datos para orquestar / intermediar la cola. Ser sin intermediarios tiene la ventaja de ser mucho más simple de administrar operativamente que las colas de mensajes con intermediarios, y de ser más simple de entender, escalar y personalizar, pero la principal desventaja es que carece de los servicios que generalmente brindan los intermediarios, por lo que si un participante es desconectado, los mensajes se pueden perder. Si necesita que el mensaje se procese de manera confiable, deberá diseñar a sus productores para que puedan manejar el envío de reintentos si el consumidor no está disponible, deberá agregar un mecanismo para el reconocimiento de la entrega exitosa y las necesidades del consumidor estar diseñado para ser idempotente (ser capaz de detectar mensajes duplicados y descartarlos). La principal ventaja de no tener intermediarios es que puede implementar tanto o tan poco comportamiento de intermediario como necesite su aplicación, por lo que no está atado a un comportamiento de intermediario específico.

Una cola de mensajes con intermediarios como RabbitMQ es algo más simple durante el uso, ya que el intermediario agrega una capa de confiabilidad de mensajería y persistencia a la estructura del sistema de cola en lugar de requerir que el productor y los consumidores las implementen, pero agrega la complejidad y los gastos generales de la administración del intermediario. y el corredor agrega latencia, por lo que puede no ser adecuado para escenarios en los que los milisegundos son importantes o donde su nivel de escalabilidad objetivo excede lo que se puede lograr en un sistema con intermediario.

todavía existe algún nivel de sobrecarga para realizar una tarea sin relaciones

Le sugiero que cree un perfil de su aplicación para averiguar si eso realmente importa o no. Lo más probable es que si una base de datos SQL en proceso no es suficiente para una aplicación no concurrente, lo más probable es que se deba a que la está utilizando de manera ineficiente, en lugar de a problemas de rendimiento en la gestión de relaciones en sí.