cqrs event-sourcing apache-kafka dddd

Usando Kafka como un(CQRS) Eventstore. ¿Buena idea?



event-sourcing apache-kafka (5)

Kafka está destinado a ser un sistema de mensajería que tiene muchas similitudes con una tienda de eventos, sin embargo, para citar su introducción:

El clúster de Kafka conserva todos los mensajes publicados, hayan sido consumidos o no, durante un período configurable de tiempo . Por ejemplo, si la retención se establece durante dos días, durante los dos días posteriores a la publicación de un mensaje está disponible para el consumo, después de lo cual se descartará para liberar espacio. El rendimiento de Kafka es efectivamente constante con respecto al tamaño de los datos, por lo que retener gran cantidad de datos no es un problema.

Entonces, aunque los mensajes pueden retenerse indefinidamente, la expectativa es que serán eliminados. Esto no significa que no pueda usar esto como una tienda de eventos, pero puede ser mejor usar otra cosa. Eche un vistazo a EventStore para una alternativa.

ACTUALIZAR

Documentación de Kafka :

El aprovisionamiento de eventos es un estilo de diseño de aplicaciones donde los cambios de estado se registran como una secuencia de registros ordenados por tiempo. El soporte de Kafka para datos de registro almacenados muy grandes lo convierte en un excelente back-end para una aplicación construida en este estilo.

ACTUALIZACIÓN 2

Una preocupación con el uso de Kafka para el abastecimiento de eventos es la cantidad de temas requeridos. Por lo general, en el abastecimiento de eventos, hay un flujo (tema) de eventos por entidad (como usuario, producto, etc.). De esta forma, el estado actual de una entidad puede reconstituirse volviendo a aplicar todos los eventos en la secuencia. Cada tema de Kafka consta de una o más particiones y cada partición se almacena como un directorio en el sistema de archivos. También habrá presión de ZooKeeper a medida que aumente el número de znodes.

Aunque me he encontrado con Kafka anteriormente, recientemente me di cuenta de que quizás Kafka pueda usarse como (la base de) un CQRS , una CQRS eventstore .

Uno de los puntos principales que Kafka admite:

  • Captura / almacenamiento de eventos, todos HA por supuesto.
  • Pub / sub arquitectura
  • Posibilidad de reproducir el registro de eventos que permite a los nuevos suscriptores registrarse en el sistema después del hecho.

Es cierto que no estoy 100% versado en CQRS / Event sourcing, pero esto parece bastante parecido a lo que debería ser un evento. Lo curioso es que realmente no puedo encontrar mucho sobre Kafka como tienda de eventos, así que quizás me esté perdiendo algo.

Entonces, ¿falta algo de Kafka para que sea una buena tienda de eventos? ¿Funcionaría? Utilizándolo Producción? Interesado en visión, enlaces, etc.

Básicamente, el estado del sistema se guarda en función de las transacciones / eventos que el sistema haya recibido alguna vez, en lugar de simplemente guardar el estado / instantánea actual del sistema, que es lo que generalmente se hace. (Piénselo como un libro mayor en Contabilidad: todas las transacciones finalmente se suman al estado final) Esto permite todo tipo de cosas interesantes, pero solo lea en los enlaces provistos.


Puede usar Kafka como tienda de eventos, pero no lo recomiendo, aunque podría parecer una buena opción:

  • Kafka solo garantiza al menos una entrega y hay duplicados en la tienda de eventos que no se pueden eliminar. Actualización: Aquí puede leer por qué es tan difícil con Kafka y algunas últimas noticias sobre cómo finalmente lograr este comportamiento: https://www.confluent.io/blog/exactly-once-semantics-are-possible-heres-how-apache-kafka-does-it/
  • Debido a la inmutabilidad, no hay forma de manipular la tienda de eventos cuando la aplicación evoluciona y los eventos necesitan ser transformados (hay, por supuesto, métodos como upcasting, pero ...). Una vez podría decir que nunca necesita transformar eventos, pero esa no es la suposición correcta, podría haber una situación en la que haga una copia de seguridad del original, pero los actualice a las versiones más recientes. Ese es un requisito válido en arquitecturas impulsadas por eventos.
  • No hay lugar para persistir instantáneas de entidades / agregados y la reproducción se volverá lenta y lenta. La creación de instantáneas es una característica imprescindible para la tienda de eventos desde una perspectiva a largo plazo.
  • Dado que las particiones de Kafka se distribuyen, son difíciles de administrar y las copias de seguridad se comparan con las bases de datos. Las bases de datos son simplemente más simples :-)

Entonces, antes de hacer su elección, piense dos veces. La tienda de eventos como combinación de interfaces de capa de aplicación (monitoreo y administración), SQL / NoSQL store y Kafka como intermediario es una mejor opción que dejar que Kafka maneje ambos roles para crear la solución completa de características completas.

La tienda de eventos es un servicio complejo que requiere más de lo que Kafka puede ofrecer si se toma en serio la posibilidad de aplicar Event sourcing, CQRS, Sagas y otros patrones en la arquitectura de eventos y mantener un alto rendimiento.

¡No dude en desafiar mi respuesta! Puede que no le guste lo que digo acerca de su broker favorito con muchas capacidades superpuestas, pero aún así, Kafka no fue diseñada como tienda de eventos, sino más como broker y buffer de alto rendimiento al mismo tiempo para manejar productores rápidos versus escenarios de consumidores lentos. por ejemplo.

Consulte eventuate.io microservices open source framework para descubrir más sobre los posibles problemas: http://eventuate.io/

Actualización a partir del 8 de febrero de 2018

No incorporo nueva información de los comentarios, pero estoy de acuerdo en algunos de esos aspectos. Esta actualización trata más sobre algunas recomendaciones para la plataforma impulsada por eventos de microservicio. Si está interesado en el diseño robusto de microservicios y el rendimiento más alto posible en general, le proporcionaré algunos consejos que podrían interesarle.

  1. No use Spring - es genial (lo uso mucho), pero es pesado y lento al mismo tiempo. Y no es una plataforma de microservicio en absoluto. Es "solo" un marco para ayudarte a implementar uno (mucho trabajo detrás de esto ...). Otros marcos son "solo" RESTO ligero o JPA o marcos enfocados de forma diferente. Recomiendo probablemente la mejor plataforma de microservicio de código abierto disponible en su clase, que está volviendo a las raíces de Java puro: https://github.com/networknt

Si se pregunta sobre el rendimiento, puede compararlo con el paquete de referencia existente. https://github.com/networknt/microservices-framework-benchmark

  1. No uses Kafka para nada :-)) Es mitad broma. Quiero decir, mientras que Kafka es genial, es otro sistema centrado en intermediarios. Creo que el futuro está en los sistemas de mensajería sin intermediarios. Puede que se sorprenda, pero hay sistemas más rápidos que Kafka :-), por supuesto, debe bajar al nivel inferior. Mira Crónica.

  2. Para la tienda de eventos, recomiendo una extensión Postgresql superior llamada TimescaleDB, que se enfoca en el procesamiento de datos de series temporales de alto rendimiento (los eventos son series de tiempo) en gran volumen. Por supuesto, CQRS, las características de abastecimiento de eventos (reproducción, etc.) están construidas en light4j framework, que utiliza Postgres como almacenamiento bajo.

  3. Para mensajes, intente ver Crónica Cola, Mapa, Motor, Red. Me refiero a deshacerse de estas soluciones anticuadas de broker e ir con el sistema de micro mensajería (integrado). Chronicle Queue es en realidad incluso más rápido que Kafka. Pero estoy de acuerdo en que no es una solución única y que necesitas desarrollar algo, de lo contrario, compra la versión Enterprise (pagada). Al final, el esfuerzo para construir desde Chronicle su propia capa de mensajes se pagará al eliminar la carga de mantener el clúster de Kafka.


Sí, puedes usar Kafka como una tienda de eventos. Funciona bastante bien, especialmente con la introducción de Kafka Streams , que proporciona una forma nativa de Kafka de procesar sus eventos en un estado acumulado que puede consultar .

Respecto a:

Posibilidad de reproducir el registro de eventos que permite a los nuevos suscriptores registrarse en el sistema después del hecho.

Esto puede ser complicado. Lo cubrí en detalle aquí: https://.com/a/48482974/741970


Soy uno de los autores originales de Kafka. Kafka funcionará muy bien como registro para el abastecimiento de eventos. Es tolerante a fallas, escala a enormes tamaños de datos y tiene un modelo de partición integrado.

Lo usamos para varios casos de uso de este formulario en LinkedIn. Por ejemplo, nuestro sistema de procesamiento de flujo de código abierto, Apache Samza, viene con soporte integrado para el abastecimiento de eventos.

Creo que no se escucha mucho sobre el uso de Kafka para el suministro de eventos, principalmente porque la terminología de abastecimiento de eventos no parece ser muy frecuente en el espacio web del consumidor donde Kafka es más popular.

He escrito un poco sobre este estilo de uso de Kafka here .


Sigo volviendo a este control de calidad. Y no encontré las respuestas existentes matizadas lo suficiente, así que estoy agregando esta.

TL; DR. Sí o No, dependiendo del uso de su evento.

Hay dos tipos principales de sistemas de origen de eventos de los cuales soy consciente.

Procesadores de eventos en sentido descendente = Sí

En este tipo de sistema, los eventos ocurren en el mundo real y se registran como hechos. Como un sistema de almacén para realizar un seguimiento de las paletas de productos. Básicamente no hay eventos conflictivos. Todo ya ha sucedido, incluso si fue incorrecto. (Es decir, el palet 123456 se puso en el camión A, pero estaba programado para el camión B.) Luego, más adelante, se verifican los hechos para detectar excepciones a través de los mecanismos de notificación. Kafka parece muy adecuado para este tipo de aplicación de procesamiento de eventos de flujo descendente.

En este contexto, es comprensible por qué la gente de Kafka lo defiende como una solución de Event Sourcing. Porque es bastante similar a la forma en que ya se utiliza, por ejemplo, en las transmisiones de clics. Sin embargo, las personas que utilizan el término Event Sourcing (en lugar de Stream Processing) probablemente se refieran al segundo uso ...

Fuente de verdad controlada por la aplicación = No

Este tipo de aplicación declara sus propios eventos como resultado de solicitudes de usuarios que pasan a través de la lógica comercial. Kafka no funciona bien en este caso por dos razones principales.

La falta de aislamiento de la entidad

Este escenario necesita la capacidad de cargar la secuencia de eventos para una entidad específica. La razón común para esto es construir un modelo de escritura transitoria para la lógica de negocios que se utilizará para procesar la solicitud. Hacer esto no es práctico en Kafka. Usar topic-per-entity podría permitir esto, excepto que este no es un iniciador cuando puede haber miles o millones de esa entidad. Esto se debe a límites técnicos en Kafka / Zookeeper. En cambio, se recomienda utilizar el tema por tipo para Kafka, pero esto requeriría cargar eventos para cada entidad de ese tipo solo para obtener eventos para una sola entidad. Dado que no puede decir por posición de registro qué eventos pertenecen a qué entidad. Incluso usando Snapshots para comenzar desde una posición de registro conocida, esto podría ser un número significativo de eventos para batir. Pero las instantáneas no pueden ayudarte con los cambios de código. Debido a que la adición de nuevas funciones a la lógica comercial puede volverse incompatibles estructuralmente las instantáneas anteriores. Por lo tanto, sigue siendo necesario repetir el tema en esos casos para construir un nuevo modelo. Una de las razones principales para usar un modelo de escritura transitoria en lugar de uno persistente es hacer que los cambios en la lógica de negocios sean baratos y fáciles de implementar.

Falta de detección de conflicto

En segundo lugar, los usuarios pueden crear condiciones de carrera debido a solicitudes concurrentes contra la misma entidad. Puede ser bastante indeseable guardar eventos conflictivos y resolverlos después del hecho. Por lo tanto, es importante poder evitar eventos conflictivos. Para escalar la carga de solicitudes, es común usar servicios sin estado mientras se previenen los conflictos de escritura usando escrituras condicionales (solo escriba si el último evento de la entidad fue #x). Aka Concurrencia optimista. Kafka no admite concurrencia optimista. Incluso si lo admite en el nivel de tema, tendría que ser todo el camino hasta el nivel de entidad para ser eficaz. Para usar Kafka y evitar eventos conflictivos, necesitaría usar un escritor con estado y serializado a nivel de aplicación. Este es un requisito arquitectónico significativo / restricción.

Más información