patron microservicios ddd arquitectura domain-driven-design cqrs consistency nosql

domain driven design - microservicios - Elegir una base de datos NoSQL para almacenar eventos en una aplicaciĆ³n diseƱada por CQRS



ddd microservicios (2)

Tengo un trabajo, en la implementación de producción de MongoDB como una Event store . Es utilizado por una aplicación de CRM basada en web de CQRS + Event sourcing .

Con el fin de proporcionar una garantía del 100% sin transacción pero similar a una transacción para eventos persistentes múltiples de una vez (todos los eventos o ninguno), utilizo un MongoDB document como una events commit , con eventos como nested documents . Como sabe, MongoDB tiene bloqueo de nivel de documento .

Para la concurrencia utilizo el bloqueo optimista, usando una propiedad de version para cada Aggregate steam . El dublet identifica una secuencia de Aggregate class ( Aggregate class Aggregate ID x Aggregate ID ).

El almacén de eventos también almacena los commits en orden relativo usando una sequence en cada commit , incrementada en cada commit, protegida usando un bloqueo optimista.

Cada commit contiene lo siguiente:

  • aggregateId: cadena, probablemente un GUID ,
  • aggregateClass: cadena,
  • version: integer, incrementado para cada aggregateId x aggregateClass,
  • secuencia, entero, incrementado para cada confirmación,
  • createdAt: UTCDateTime,
  • authenticatedUserId: string o null,
  • eventos: lista de EventWithMetadata ,

Cada EventWithMetadata contiene la event class/type y la carga útil como cadena (la versión serializada del evento real).

La colección MongoDB tiene los siguientes índices:

  • aggregateId , aggregateClass , version como unique
  • events.eventClass , sequence
  • sequence
  • otros índices para la optimización de consultas

Estos índices se usan para aplicar las reglas generales de la tienda de eventos (no se almacenan eventos para la misma versión de un Aggregate ) y para optimizaciones de consultas (el cliente puede seleccionar solo ciertos eventos , por tipo, de todas las transmisiones ).

Puede usar sharding por aggregateId a escala, si elimina el orden global de eventos (la propiedad de sequence ) y traslada esa responsabilidad a un event publisher pero esto complica las cosas ya que el event publisher del event publisher necesita permanecer sincronizado (¡incluso en caso de error! ) con la event store . Recomiendo hacerlo solo si lo necesitas.

Puntos de referencia para esta implementación (en Intel I7 con 8GB de RAM ):

  • el tiempo total de escritura agregado fue: 7.99, velocidad: 12516 eventos escribieron por segundo
  • el tiempo de lectura agregado total fue: 1.43, velocidad: 35036 eventos leídos por segundo
  • el tiempo total de lectura del modelo de lectura fue: 3.26, velocidad: 30679 eventos leídos por segundo

Me he dado cuenta de que MongoDB tardó en counting la cantidad de eventos en la tienda de eventos. No sé por qué, pero no me importa, ya que no necesito esta característica.

Recomiendo usar MongoDB como una event store .

Estoy buscando una explicación buena, actualizada y de "ayuda para la toma de decisiones" sobre cómo elegir un motor de base de datos NoSQL para almacenar todos los eventos en una aplicación diseñada por CQRS.

Actualmente soy un recién llegado a todo lo relacionado con NoSQL (pero estoy aprendiendo): por favor, sean claros y no duden en explicar su punto de vista de una manera (casi demasiado) precisa. Esta publicación puede merecer otros recién llegados como yo.

Esta base de datos:

  • Ser capaz de insertar de 2 a 10 filas por cada actualización solicitada por la vista frontal (en mi caso, las actualizaciones son frecuentes). Piense en miles de actualizaciones por minuto, ¿cómo se escalaría?

  • Críticamente, debe ser coherente y seguro ante fallas , ya que los eventos son la fuente de la verdad de la aplicación

  • No necesita ningún enlace entre entidades (como RDBMS), excepto tal vez un ID de usuario / GUID (no sé si es crítico o aún necesario)

  • Reciba eventos que contengan de 3 a 10 "columnas" (una identificación de secuencia, un nombre de evento, una fecha y hora, un paquete de parámetros codificado JSON / binario, algunas informaciones de contexto ...). Sin orientar su punto de vista en un tipo de base de datos orientada a columnas, puede estar orientado a documentos si se ajusta a todos los demás requisitos

  • Ser utilizado como una cola o enviado / leído desde un sistema AMQP externo como RabbitMQ o ZeroMQ (aún no funcionó esa parte, si también se puede argumentar / explicar ...) ya que las proyecciones de vista se construirán sobre eventos

  • Necesita algún tipo de filtrado por ID de secuencia como SELECT * FROM events WHERE sequence_id > last_sequence_id para suscriptores (o sistemas de cola) para poder sincronizar desde un punto determinado

Escuché de HBase para el almacenamiento de eventos CQRS, pero tal vez MongoDB podría caber? O incluso Elasticsearch (no apostaría por eso ...)? También estoy abierto a RDBMS por coherencia y disponibilidad ... pero ¿qué pasa con la parte de tolerancia de partición ...?

Realmente estoy perdido, necesito argumentos para hacer una elección pertinente.


https://geteventstore.com/ es una base de datos diseñada específicamente para secuencias de eventos.

Toman la consistencia y la fiabilidad de la fuente de la verdad (sus eventos) muy en serio y yo mismo la uso para leer / escribir miles de eventos por segundo.