Arquitectura de referencia: orientada a eventos / CQRS
En una arquitectura orientada a eventos, los servicios publican eventos en un log de eventos (p. ej. Kafka) en lugar de llamarse directamente entre sí, y los consumidores los procesan de forma asíncrona. Partiendo de la construcción de la columna vertebral de eventos, este árbol recorre paso a paso el event sourcing (derivar el estado a partir de los eventos), la separación de comandos/consultas con CQRS, la proyección del modelo de lectura, la idempotencia, la tolerancia a la consistencia eventual y la falacia de la «entrega exactly-once». El objetivo es un sistema débilmente acoplado y escalable cuyos compromisos de consistencia se entiendan bien.
¿Qué decisión afronta en su arquitectura orientada a eventos?
La base de un sistema orientado a eventos es un log de eventos duradero que conecta los servicios mediante eventos asíncronos. ¿Sigue construyendo la columna vertebral, quiere derivar el estado a partir de los eventos (event sourcing), o está separando las rutas de lectura y escritura (CQRS)?
- Estoy construyendo la columna vertebral de eventos que conecta los servicios
- Quiero derivar el estado a partir del historial de eventos
- Quiero separar las rutas de lectura y escritura (CQRS)
¿Cómo construirá el lado de lectura en CQRS y cuál es su tolerancia de consistencia?
En CQRS, los lados de comando (escritura) y de consulta (lectura) están separados; los eventos de escritura actualizan la proyección que alimenta el modelo de lectura. La pregunta clave: ¿puede tolerar que el modelo de lectura vaya por detrás de las escrituras (consistencia eventual), o espera que cada evento se procese exactamente una vez?
- Alimentaré el modelo de lectura a partir de los eventos mediante una proyección
- Las lecturas deben estar actualizadas; el retraso es inaceptable
- Quiero que los eventos se procesen «exactamente una vez»
Recomendación: una columna vertebral de log de eventos duradero
En el centro de una arquitectura orientada a eventos hay un log de eventos duradero y ordenado en el que escriben los productores y que los consumidores leen a su propio ritmo. Esta columna vertebral desacopla los servicios en el tiempo y en la escala.
Recomendación: event sourcing (derivar el estado a partir de los eventos)
En event sourcing no se almacena el estado actual de una entidad, sino todos los eventos de cambio (inmutables) que se le han aplicado; el estado actual se deriva aplicando estos eventos en orden. Proporciona un historial de auditoría completo y la capacidad de volver a cualquier punto del pasado.
Recomendación: proyección del modelo de lectura
En CQRS, el lado de escritura produce eventos; una proyección escucha estos eventos y actualiza un modelo de lectura optimizado para consultas (vista desnormalizada). Las lecturas se sirven desde este modelo ya preparado, completamente separado de la ruta de escritura, y ambos lados escalan de forma independiente.
Recomendación: diseñe para tolerar la consistencia eventual
En los sistemas orientados a eventos/CQRS, el modelo de lectura va ligeramente por detrás de las escrituras (consistencia eventual). En lugar de intentar «eliminarlo», diseñe para tolerarlo; mantenga separados los pocos flujos que requieren consistencia inmediata estricta.
Recomendación: idempotencia (la falacia del exactly-once)
En la mensajería distribuida, la «entrega exactly-once» de extremo a extremo es en la práctica una falacia; los mensajes duplicados son inevitables por la red y los reintentos. El objetivo correcto es el procesamiento idempotente: procesar dos veces el mismo evento debe dar el mismo resultado que procesarlo una vez.