Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Event Sourcing - El valor de la información

Diego Martin
September 28, 2019

Event Sourcing - El valor de la información

Esta es una presentación de Diego Martín, fundador de Sunny Attic Software (https://sunnyatticsoftware.com) presentada en la DotNetMalaga 2019.
En ella se habla del concepto de eventos como hechos inmutables y de los sistemas Event Sourcing donde el estado, que es transitorio, no es el que se guarda, sino que se infiere a partir del histórico de eventos.
Después se habla de CQRS y de cómo CQRS sirve de herramienta para conseguir escalado horizontal, caché infinita, optimización del proceso de lectura, etc. Se explica por qué CQRS nos permite utilizar Event Sourcing y cómo Domain Driven Design nos ayuda a modelar el dominio para utilizar la consistencia eventual en nuestro favor.
Finalmente se discute una técnica de versionado de eventos con weak-schema y una forma de implementar protección de datos (i.e: ley GDPR) en sistemas Event Sourcing.

Diego Martin

September 28, 2019
Tweet

More Decks by Diego Martin

Other Decks in Programming

Transcript

  1. Algunos autores de cabecera 2 Robert C. Martin Martin Fowler

    Diego Martín …y otros HTTPS://SUNNYATTICSOFTWARE.COM
  2. Account-123 # Event 1 AccountCreated 2 SalaryReceived 3 PaymentMade 4

    PaymentMade 5 InterestReceived 6 PaymentReverted Balance Account-123 3050 Event Stream Agrupa eventos Dentro de un Event Log Estado 5 HTTPS://SUNNYATTICSOFTWARE.COM
  3. Account-123 # Event 1 AccountCreated 2 SalaryReceived 3 PaymentMade 4

    PaymentMade 5 InterestReceived 6 PaymentReverted { “AggregateId”: “123”, “EventId”: “abc” } Balance Account-123 0 6 HTTPS://SUNNYATTICSOFTWARE.COM
  4. Account-123 # Event 1 AccountCreated 2 SalaryReceived 3 PaymentMade 4

    PaymentMade 5 InterestReceived 6 PaymentReverted { “AggregateId”: “123”, “EventId”: “abd”, “Company”: “Iberodev S.L”, “Amount”: 4000.00, “CurrencyCode”: EUR } Balance Account-123 4000 7 HTTPS://SUNNYATTICSOFTWARE.COM
  5. Account-123 # Event 1 AccountCreated 2 SalaryReceived 3 PaymentMade 4

    PaymentMade 5 InterestReceived 6 PaymentReverted { “AggregateId”: “123”, “EventId”: “abe” “Destination”: “Amazon”, “IsDebited”: true, “Amount”: 500.00, “CurrencyCode”: EUR } Balance Account-123 3500 8 HTTPS://SUNNYATTICSOFTWARE.COM
  6. Account-123 # Event 1 AccountCreated 2 SalaryReceived 3 PaymentMade 4

    PaymentMade 5 InterestReceived 6 PaymentReverted { “AggregateId”: “123”, “EventId”: “abf”, “Destination”: “Telepizza”, “IsDebited”: true, “Amount”: 1000.00, “CurrencyCode”: EUR } Balance Account-123 2500 9 HTTPS://SUNNYATTICSOFTWARE.COM
  7. Account-123 # Event 1 AccountCreated 2 SalaryReceived 3 PaymentMade 4

    PaymentMade 5 InterestReceived 6 PaymentReverted { “AggregateId”: “123”, “EventId”: “abg”, “Reason”: “Acc 3.75% TAE”, “Amount”: 50.00, “CurrencyCode”: EUR } Balance Account-123 2550 10 HTTPS://SUNNYATTICSOFTWARE.COM
  8. Account-123 # Event 1 AccountCreated 2 SalaryReceived 3 PaymentMade 4

    PaymentMade 5 InterestReceived 6 PaymentReverted { “AggregateId”: “123”, “EventId”: “abh”, “RefersToEventId”: “abe”, “Reason”: “Mistake”, “Amount”: 500.00, “CurrencyCode”: EUR } Balance Account-123 3050 Estado actual 11 HTTPS://SUNNYATTICSOFTWARE.COM
  9. CarritoCreado ProductoAñadido Los eventos son Append-Only ProductoAñadido ProductoAñadido 0 ProductoQuitado

    CarritoConfirmado 1 2 3 2 y… venta creada!! 13 HTTPS://SUNNYATTICSOFTWARE.COM
  10. Carrito Venta Producto * Esto es un modelo Entidad-Relación de

    toda la vida 2 0..1 14 HTTPS://SUNNYATTICSOFTWARE.COM
  11. Replay CarritoCreado ProductoAñadido ProductoAñadido ProductoAñadido ProductoQuitado CarritoConfirmado CarritoCreado ProductoAñadido ProductoAñadido

    CarritoConfirmado ¿No es lo mismo? VS 2 Carrito Venta Producto * 0..1 16 HTTPS://SUNNYATTICSOFTWARE.COM
  12. CarritoCreado ProductoAñadido ProductoAñadido ProductoAñadido ProductoQuitado CarritoConfirmado Qué vs Cómo Replay

    ¿Quién conoce el valor futuro de la información? 17 HTTPS://SUNNYATTICSOFTWARE.COM
  13. CarritoCreado ProductoAñadido ProductoAñadido ProductoAñadido ProductoQuitado CarritoConfirmado Replay Carrito id ventaId

    fechaCreacion 1 9923 27/09/2019 Producto id carritoId codigo nombre 123 1 ma001123 Mesa azul 124 1 sa098443 Silla azul Venta id carritoId importe moneda 9923 1 275.26 EUR 18 HTTPS://SUNNYATTICSOFTWARE.COM
  14. CarritoCreado ProductoAñadido ProductoAñadido ProductoAñadido ProductoQuitado CarritoConfirmado Replay Carrito id fechaCreacion

    productos total 1 27/09/2019 ma001123, sa098443 257.26 2 28/09/2019 Libro Eric Evans DDD 42.50 VentaCompleta id fechaCreacion productos total 1 27/09/2019 ma001123, sa098443 257.26 19 HTTPS://SUNNYATTICSOFTWARE.COM
  15. CarritoCreado ProductoAñadido ProductoAñadido ProductoAñadido ProductoQuitado CarritoConfirmado Replay ProductoQuitado id producto

    msHastaOk precio email 1 vb157486 4302 423.25 [email protected] Las Proyecciones son reportes que tienen en cuenta todo el histórico de eventos 20 HTTPS://SUNNYATTICSOFTWARE.COM
  16. Con Event Sourcing no se pierde información Create Read Update

    Delete Concurrencia problemática Optimización de escritura y concurrencia optimística 21 HTTPS://SUNNYATTICSOFTWARE.COM
  17. “Asking a question should not change the answer” Bertrand Meyer

    void DoSomething(arg); // command object GetSomething(arg); // query CQRS Command Query Responsibility Segregation CQS Command Query Separation 25 HTTPS://SUNNYATTICSOFTWARE.COM
  18. Base de Datos Objeto de Dominio Objeto de Dominio Aplicación

    Façade Remota Cliente Envío DTO return status Petición DTO return DTO Esto es una arquitectura CRUD de DTO up/down de toda la vida 26 HTTPS://SUNNYATTICSOFTWARE.COM
  19. Base de Datos Objeto de Dominio Objeto de Dominio Aplicación

    Façade Remota Command Base de Datos Aplicación Façade Remota Cliente Query 27 HTTPS://SUNNYATTICSOFTWARE.COM
  20. Façade Remota Command Handler Domain Object Repository Command Event Command

    Service Façade Remota Query Event Handler Repository Query Service 28 HTTPS://SUNNYATTICSOFTWARE.COM
  21. Façade Remota Command Handler Domain Object Repository Command Event Store

    Events Command Service Façade Remota Query Event Handler Repository Query Service 30 HTTPS://SUNNYATTICSOFTWARE.COM
  22. Command Service Event Store Query Service Query Service Query Service

    Nuevo Read Model subscriptor publicador Replay de eventos desde posición 0 31 HTTPS://SUNNYATTICSOFTWARE.COM
  23. Pero.. ¿y si el query service tarda demasiado en recibir

    el evento? 32 HTTPS://SUNNYATTICSOFTWARE.COM
  24. CQRS consigue AP y consistencia eventual “Consistency, Availability, Partition Tolerance.

    Choose only two” Eric Brewer – CAP Theorem CQRS + Event Sourcing DDD 34 HTTPS://SUNNYATTICSOFTWARE.COM
  25. ¿Y los cambios en la estructura (versionado)? Más info Menos

    info Diferente info 35 HTTPS://SUNNYATTICSOFTWARE.COM
  26. { “AggregateId”: “123”, “Fecha”: “2003-04-21”, “Codigo”: 500 } EventLog #

    Event … … 96852 ProductoAñadido 96852 ProductoAñadido … … 102656 ProductoAñadido … … 113584 ProductoAñadido … … { “AggregateId”: “123”, “CodigoProducto”: 650, “Tienda”: “Llevatelo S.L” } = Más info Menos info Diferente info 36 HTTPS://SUNNYATTICSOFTWARE.COM
  27. Hay muchas estrategias… Double-Write Upcasting Weak-Schema mapping “A new version

    of an event must be convertible from the old version of the event. If not, it is not a new version of the event but rather a new event” Greg Young 37 HTTPS://SUNNYATTICSOFTWARE.COM
  28. Cliente Event Store Cliente Cliente Diferentes “versiones” del mismo evento

    Conoce la primera versión class ProductoAñadido { string AggregateId {get;set;} DateTime Fecha {get;set;} int Codigo {get;set;} } Conoce la segunda versión Conoce la última versión class ProductoAñadido { string AggregateId {get;set;} int Codigo {get;set;} string Tienda {get;set;} } class ProductoAñadido { string AggregateId {get;set;} int CodigoProducto {get;set;} string Tienda {get;set;} } 38 HTTPS://SUNNYATTICSOFTWARE.COM
  29. Cliente Event Store class ProductoAñadido { string AggregateId {get;set;} //

    “123” DateTime Fecha {get;set;} // 2003-04-21 int Codigo {get;set;} // 500 } { “AggregateId”: “123”, “Fecha”: “2003-04-21”, “Codigo”: 500 } Cliente Cliente class ProductoAñadido { string AggregateId {get;set;} // “123” int Codigo {get;set;} // 500 string Tienda {get;set;} // null (default) } class ProductoAñadido { string AggregateId {get;set;} // “123” int CodigoProducto {get;set;} // 0 (default) string Tienda {get;set;} // null (default) } v1 39 HTTPS://SUNNYATTICSOFTWARE.COM
  30. Cliente Event Store class ProductoAñadido { string AggregateId {get;set;} //

    “123” DateTime Fecha {get;set;} // 0001-01-01 (default) int Codigo {get;set;} // 500 } { “AggregateId”: “123”, “Codigo”: 500, “Tienda”: “Llevatelo S.L” } Cliente Cliente class ProductoAñadido { string AggregateId {get;set;} // “123” int Codigo {get;set;} // 500 string Tienda {get;set;} // “Llevatelo S.L” } class ProductoAñadido { string AggregateId {get;set;} // “123” int CodigoProducto {get;set;} // 0 (default) string Tienda {get;set;} // “Llevatelo S.L” } v2 40 HTTPS://SUNNYATTICSOFTWARE.COM
  31. Cliente Event Store class ProductoAñadido { string AggregateId {get;set;} //

    “123” DateTime Fecha {get;set;} // 0001-01-01 (default) int Codigo {get;set;} // 0 (default) } { “AggregateId”: “123”, “CodigoProducto”: 650, “Tienda”: “Llevatelo S.L” } Cliente Cliente class ProductoAñadido { string AggregateId {get;set;} // “123” int Codigo {get;set;} // 0 (default) string Tienda {get;set;} // “Llevatelo S.L” } class ProductoAñadido { string AggregateId {get;set;} // “123” int CodigoProducto {get;set;} // 650 string Tienda {get;set;} // “Llevatelo S.L” } v3 41 HTTPS://SUNNYATTICSOFTWARE.COM
  32. Al versionar eventos Sin problema para añadir Cuidado al borrar

    Cuidado al renombrar (= borrar + añadir) 42 HTTPS://SUNNYATTICSOFTWARE.COM
  33. Event Store { “AggregateId”: “123”, “Codigo”: 500, “Tienda”: “Llevatelo S.L”

    } Cliente v2 class ProductoAñadido { string AggregateId {get;} // “123” int CodigoProducto => Codigo // 500 string Tienda {get;} // “Llevatelo S.L” [Obsolete] int Codigo {get;} public ProductoAñadido( string aggregateId, int codigo, int codigoProducto, string tienda) { AggregateId = aggregateId; Codigo = codigoProducto != 0 ? codigoProducto : codigo; Tienda = tienda } } mapping 44 HTTPS://SUNNYATTICSOFTWARE.COM
  34. Event Store EventLog o Stream Event … ProductoAñadido … New

    EventLog o Stream Event … ReservaProductoAñadido … copy & replace Event Store 46 HTTPS://SUNNYATTICSOFTWARE.COM
  35. Event Storage Encriptación clave simetrica Key Storage DataSubjectId EncryptionKey IsDeleted

    123 Ab7…9fsFs= false 124 gRR…vs3Ag= true 125 R2f…5sGfl= false class ClienteAñadido { string Nombre {get;} // Diego Martin DateTime Nacimiento {get;} // 1984-01-01 string CodigoPais {get;} // ES } { “nombre”: “GFfsd4afREWsfsgfadsdf=”, “nacimiento”: “fhh4gsdVgasgr65fGG=”, “codigoPais”: ES } { “nombre”: “GFfsd4afREWsfsgfadsdf=”, “nacimiento”: “fhh4gsdVgasgr65fGG=”, “codigoPais”: ES } Desencriptación clave simetrica class ClienteAñadido { string Nombre {get;} // ******, DateTime Nacimiento {get;} // 0001-01-01 string CodigoPais {get;} // ES } 48 HTTPS://SUNNYATTICSOFTWARE.COM
  36. https://eventstore.org Base de datos open source para streams de eventos

    Multiplataforma, implementado en un mix de C# (con Mono), C++ y Javascript 50 HTTPS://SUNNYATTICSOFTWARE.COM