DomCode 2017 - The Dark Side of Event Sourcing

DomCode 2017 - The Dark Side of Event Sourcing

"Event sourcing is easy!" they said. "Just record all of your user events" they said. "They're always useful." they said. So you did. You kept all the events. All of them. And now that you have them, there's just one question on your mind: How the heck do I manage all of it?!

Fear not. This month, two speakers we have. Powerful event wizards they are. Speak about the Dark Side of Event Sourcing they will. Remember: Collection leads to storage. Storage leads to maintenance. Maintenance leads to legacy. Legacy...leads to suffering.

03dc1d993fa7d5de422c1f35d53f80e6?s=128

Michiel Overeem

March 28, 2017
Tweet

Transcript

  1. The Dark Side of Event Sourcing Managing Data Conversion Michiel

    Overeem, Marten Spoor, Slinger Jansen
  2. Lead Software Architect @ AFAS Software PhD Candidate @ University

    Utrecht @michielovereem Software Architect @ AFAS Software @martenspoor
  3. AFAS Software 400 employees 100 million euro revenue

  4. None
  5. x 10.000

  6. x 10.000 DEV.AFAS.NL

  7. Adaptable Model-based and User-specific Software Ecosystems

  8. Copyright Nasa Goddard

  9. None
  10. How can an event sourced system be upgraded efficiently when

    the (implicit) event schema changes? Operations Techniques Strategies
  11. Event sourcing Event BankAccountCreated (accountId: 1234567, balance: 0, owner: Michiel);

    accountId balance owner 1234567 0 Michiel Current state Event sourcing
  12. Event sourcing Event BankAccountCreated (accountId: 1234567, balance: 0, owner: Michiel);

    DepositPerformed (accountId : 1234567, amount: 100, balance: 100); accountId balance owner 1234567 100 Michiel Current state Event sourcing
  13. Event sourcing Event BankAccountCreated (accountId: 1234567, balance: 0, owner: Michiel);

    DepositPerformed (accountId : 1234567, amount: 100, balance: 100); WithdrawalPerformed (accountId: 1234567, amount: 50, balance: 50); accountId balance owner 1234567 50 Michiel Current state Event sourcing
  14. Event sourcing Event BankAccountCreated (accountId: 1234567, balance: 0, owner: Michiel);

    DepositPerformed (accountId : 1234567, amount: 100, balance: 100); WithdrawalPerformed (accountId: 1234567, amount: 50, balance: 50); OwnerChanged (accountId: 1234567, newOwner: Marten); accountId balance owner 1234567 50 Marten Current state Event sourcing
  15. The structure of an Event Store type Attribute = (string,

    System.Object) type Event = (string, Attribute[]) type EventStream = (string, (DateTime, Event[])[] type EventStore = EventStream[]
  16. But there is also a schema Which streams are known

    in the system? Which events are allowed in which streams? Which attributes are allowed in which events?
  17. Example schema: webshop Webshop EventStore Customer Stream ShoppingCart Stream CustomerSignedUp

    PriviligeUpgraded … AddedToChart ChangedQuantity …
  18. Add attribute to event CustomerSignedUp Newsletter: bool We add newsletter

    functionality, and users can opt-in at signup
  19. Add event to stream OptInOnNewsLetter Or opt-in at a later

    moment
  20. Add stream to store And of course management of newsletters

    Newsletter Stream Create Publish …
  21. Split attribute in event CustomerSignedUp FullName: string We chose the

    wrong attributes for name
  22. Split attribute in event CustomerSignedUp FullName: string We chose the

    wrong attributes for name CustomerSignedUp FirstName: string SurName: string
  23. Split event in stream CustomerSignedUp We created events that were

    to large
  24. Split event in stream We created events that were to

    large OptInOnNewsLetter CustomerSignedUp
  25. Split streams We found new streams Customer Stream CustomerSignedUp PriviligeUpgraded

    … Newsletter subscribers Stream OptInOnNewsLetter … …
  26. Store level operations Add / remove streams Merge streams /

    split / … streams Stream level operations Add / remove events Merge events / split / … events Event level operations Add / update / remove attributes Merge attributes / split / … attributes How can we change it?
  27. How to execute these operations? Data upgrade Application upgrade Executed

    by Basic & Complex Event Basic & Complex Stream Basic & Complex Store Techniques Strategies
  28. Multiple versions: always extend Webshop EventStore Customer Stream ShoppingCart Stream

    CustomerSignedUp PriviligeUpgraded … AddedToChart ChangedQuantity …
  29. Multiple versions: always extend Webshop EventStore Customer Stream ShoppingCart Stream

    CustomerSignedUp PriviligeUpgraded … AddedToChart ChangedQuantity … CustomerSignedUp_V2
  30. Is this maintainable? Becomes the codebase to complex?

  31. Weakening the schema Which attributes can occure in which events?

    Which events can occure in which streams? Which streams can originate in the system?
  32. Weak schema’s Webshop EventStore Customer Stream ShoppingCart Stream CustomerSignedUp PriviligeUpgraded

    … AddedToChart ChangedQuantity …
  33. Weak schema’s Webshop EventStore Customer Stream ShoppingCart Stream CustomerSignedUp PriviligeUpgraded

    … AddedToChart ChangedQuantity … CustomerSignedUp
  34. Explosion of code paths? And still not all operations are

    possible.
  35. Webshop EventStore Customer Stream ShoppingCart Stream CustomerSignedUp PriviligeUpgraded … Upcasters:

    Evolve the events AddedToChart ChangedQuantity …
  36. Webshop EventStore Customer Stream ShoppingCart Stream CustomerSignedUp PriviligeUpgraded … Upcasters:

    Evolve the events AddedToChart ChangedQuantity … CustomerSignedUp_V2
  37. What is the run-time overhead? Are all operations possible?

  38. Stream boundaries: sharding Webshop EventStore Customer Stream ShoppingCart Stream CustomerSignedUp

    PriviligeUpgraded … AddedToChart ChangedQuantity …
  39. Webshop EventStore 2 Stream boundaries: sharding Webshop EventStore 1 Customer

    Stream ShoppingCart Stream CustomerSignedUp PriviligeUpgraded … AddedToChart ChangedQuantity …
  40. How to execute these other operations? Techniques Data upgrade Application

    upgrade Executed by Executed by Basic & Complex Event Basic & Complex Stream Basic Store Complex Store Lazy transformation Upcasting Multiple versions Weak schema Strategies
  41. Copyright Stephen Cairns Technical versus functional immutability

  42. Lazy transformation

  43. But when is this finished? Mixed appends and updates.

  44. In place transformation Just find the events and fix them.

  45. Not for the faint of heart!

  46. Copy and transformation

  47. Change all the things! Auto backup. Could be very slow.

  48. Multiple versions Weak schema Upcasters Lazy transformation In place transformation

    Copy and transformation +/- - +/- +/- + + Operation completeness
  49. Multiple versions Weak schema Upcasters Lazy transformation In place transformation

    Copy and transformation - +/- +/- +/- + + Maintainability
  50. Multiple versions Weak schema Upcasters Lazy transformation In place transformation

    Copy and transformation + + + +/- +/- - Performance efficiency
  51. Multiple versions Weak schema Upcasters Lazy transformation In place transformation

    Copy and transformation + + + - - + Reliability
  52. Copyright SpaceX Data upgrade Application upgrade Executed by Executed by

    Basic & Complex Event Basic & Complex Stream Basic Store Complex Store Lazy transformation Upcasting Multiple versions Weak schema In place transfor- mation Copy and transfor- mation But how to deploy them? Strategies
  53. Big flip

  54. Big flip

  55. Big flip

  56. Big flip

  57. Big flip

  58. Big flip

  59. Blue-Green

  60. Blue-Green

  61. Blue-Green

  62. Blue-Green

  63. Blue-Green

  64. Rolling upgrade

  65. Rolling upgrade

  66. Rolling upgrade

  67. Rolling upgrade

  68. Rolling upgrade

  69. But for database deployment we need another strategy.

  70. Blue-Green

  71. Blue-Green

  72. Blue-Green

  73. Blue-Green

  74. Expand- Contract

  75. Expand- Contract

  76. Expand- Contract

  77. Expand- Contract

  78. Combining everything into a framework Data upgrade Deployed with Executed

    by Executed by Data upgrade Application upgrade Lazy transformation Upcasting In place transfor- mation Multiple versions Copy and transfor- mation Basic & Complex Event Basic & Complex Stream Basic Store Complex Store Big Flip Rolling Upgrade Blue-Green Expand- Contract Blue- Green Deployed with Combined with Weak schema
  79. Beware of the projectors! Order of upgrading components still matters!

  80. Beware of the projectors! Order of upgrading components still matters!

  81. Beware of the projectors! Order of upgrading components still matters!

  82. Beware of the projectors! Order of upgrading components still matters!

  83. But what about the query side?

  84. What’s next? 1. Do interviews. Interested? Contact me! https://goo.gl/forms/7tuBKW39EPkWnZLG3 2.

    Write a follow up paper with more information. 3. Publish the experiences in some form.
  85. Early interview results

  86. Do you read your events ever again? No? Then just

    change the snapshot.
  87. Move out all events belonging to old aggregates.

  88. Nobody uses lazy transformation.

  89. Domain driven design helps in preventing changes.

  90. There is a lack of experience sharing.

  91. Your context determines the best upgrade strategy. m.overeem@afas.nl / m.spoor@afas.nl

    @michielovereem / @martenspoor