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
comounique
-
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.