Die Welt in der wir leben und damit auch die Art wie wir Software schreiben wird immer dynamischer. Wir agieren in immer ungewisseren Kontexten, die Welt ändert sich deutlich schneller und die Systeme werden immer komplexer – so komplex dass ein einzelner Mensch oder eine kleine Gruppe nicht mehr in der Lage ist das gesamte System in Gänze zu verstehen. Dadurch sind wir heutzutage immer mehr darauf angewiesen unsere Softwaresysteme skalierbar zu schreiben, sie schnell austauschbar zu halten, robust gegenüber Fehlern zu gestalten und mehrere Versionen simultan zu unterstützen. Die große Frage die sich uns allen dabei stellt, ist es wie wir dies bewerkstelligen können? EventSourcing und CQRS sind zwei Architekturmuster, die uns dabei unterstützen können. Wir beginnen mit einem Impulsvortrag und freuen uns dann auf spannende Diskussionen rund ums Thema.
2. Experiments
are not
feasible!
• Risk to change a running system is too high!
• Huge effort to host several alternatives!
• Experiments produce insights on which we can‘t react
fast enough!
• Our technology stack doesn‘t support your idea!
• Running experiments cost too much (e. g.
implementation, seperate logging, assign experiments
to users)!
• Experiments aren‘t mature and crash the whole system!
• We can support only one version of the API at once!
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft4
4. DevOps and
Experiments
- Optimal
combo?
DevOps Goals
• Achieve accelerated and more frequent deployment of
changes to Production
• Feedback from real users as early and frequently as
possible
Continuous Delivery
• Quick deployment of components
• Automatic rollback (triggered manually / automatic)
Microservices (Philosophy)
• Non-Deployment Monoliths
• Small components (3 months / small team)
• Technology independent
• Allows different versions at runtime
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft6
5. Microservice
+
Continuous
Delivery
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft7
https://www.nginx.com/blog/introduction-to-
microservices/
http://blog.crisp.se/2013/02/05/yassalsundman/continuous-delivery-vs-continuous-deployment
6. Bounded
Context
Allow
• easier change of requirements
Need
• parallel models -> needs synchronisation16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft8
https://www.martinfowler.com/bliki/BoundedContext.html
7. Event
Sourcing
and CQRS
help
Event Sourcing
• Creation and synchronisation of parallel models
• Resilience
• Change Log
CQRS
• Separate write side from read side
• Supports parallel models (e. g. allowing only one serivce to
write data, but other services to reuse them in a way they
need)
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft9
10. Active
Record
Example: Bank Account
Domain Model
ORM
Layer
RDBMS
Load
AccountBalance
Aggregate for Account 501
0.00
ID Account Owner Balance
… … …
501 Björn Senft 0.00
502 Simon Oberthür 300.00
AccountBalance
Aggregate for Account 502
0.00
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft12
11. Active
Record
Example: Bank Account
Domain Model
ORM
Layer
RDBMS
Load
AccountBalance
Aggregate for Account 501
0.00
ID Account Owner Balance
… … …
501 Björn Senft 0.00
502 Simon Oberthür 300.00
Query results
AccountBalance
Aggregate for Account 502
300.00
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft13
12. Active
Record
Example: Bank Account
Domain Model
ORM
Layer
RDBMS
AccountBalance
Aggregate for Account 501
0.00
ID Account Owner Balance
… … …
501 Björn Senft 0.00
502 Simon Oberthür 300.00
Command:
Transfer 100€ from
Simon Oberthür to Björn Senft
AccountBalance
Aggregate for Account 502
300.00
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft14
13. Active
Record
Example: Bank Account
Domain Model
ORM
Layer
RDBMS
AccountBalance
Aggregate for Account 501
0.00
ID Account Owner Balance
… … …
501 Björn Senft 0.00
502 Simon Oberthür 300.00
Command Handler
Command:
Transfer 100€ from
Simon Oberthür to Björn Senft
AccountBalance
Aggregate for Account 502
300.00
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft15
14. Active
Record
Example: Bank Account
Domain Model
ORM
Layer
RDBMS
AccountBalance
Aggregate for Account 501
100.00
ID Account Owner Balance
… … …
501 Björn Senft 0.00
502 Simon Oberthür 300.00
Command Handler
Command:
Transfer 100€ from
Simon Oberthür to Björn Senft
AccountBalance
Aggregate for Account 502
200.00
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft16
15. Active
Record
Example: Bank Account
Domain Model
ORM
Layer
RDBMS
Save
AccountBalance
Aggregate for Account 501
100.00
ID Account Owner Balance
… … …
501 Björn Senft 0.00
502 Simon Oberthür 300.00
Command Handler
Command:
Transfer 100€ from
Simon Oberthür to Björn Senft
AccountBalance
Aggregate for Account 502
200.00
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft17
16. Active
Record
Example: Bank Account
Domain Model
ORM
Layer
RDBMS
AccountBalance
Aggregate for Account 501
100.00
ID Account Owner Balance
… … …
501 Björn Senft 100.00
502 Simon Oberthür 200.00
Update statement
Command Handler
Command:
Transfer 100€ from
Simon Oberthür to Björn Senft
AccountBalance
Aggregate for Account 502
200.00
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft18
17. Active
Record
Example: Bank Account
Domain Model
ORM
Layer
RDBMS
AccountBalance
Aggregate for Account 501
2550.00
ID Account Owner Balance
… … …
501 Björn Senft 2550.00
502 Simon Oberthür -15,300.00
AccountBalance
Aggregate for Account 502
-15,300.00
Simon Björn
What
happened?
What
happened?
Disadvantage: No history of changes!
Here: No reasoning about transactions in the past
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft20
18. Object-
relational
impedance
mismatch
• 143 pages on mapping
objects to tables
• Recommends using ORM-
Tools only for CRUD-heavy
applications
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft22
20. Event
Sourcing
Example: Bank Account
Domain Model
AccountBalance
Aggregate for Account 501
0.00
AccountBalance
Aggregate for Account 502
0.00
Event Store
Debit100€
Credit200€
…
Credit50€
Debit500€
Events
belonging to
Account 501
Query
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft24
21. Event
Sourcing
Example: Bank Account
Domain Model
AccountBalance
Aggregate for Account 501
0.00
AccountBalance
Aggregate for Account 502
300.00
Event Store
Debit100€
Credit200€
…
Credit50€
Debit500€
Events
belonging to
Account 501
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft25
22. Event
Sourcing
Example: Bank Account
Domain Model
AccountBalance
Aggregate for Account 501
0.00
AccountBalance
Aggregate for Account 502
300.00
Command:
Transfer 100€ from
Simon Oberthür to Björn Senft
Event Store
Debit100€
Credit200€
…
Credit50€
Debit500€
Events
belonging to
Account 501
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft26
23. Event
Sourcing
Example: Bank Account
Domain Model
AccountBalance
Aggregate for Account 501
0.00
AccountBalance
Aggregate for Account 502
300.00
Command Handler
Command:
Transfer 100€ from
Simon Oberthür to Björn Senft
Event Store
Debit100€
Credit200€
…
Credit50€
Debit500€
Events
belonging to
Account 501
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft27
24. Event
Sourcing
Example: Bank Account
Domain Model
AccountBalance
Aggregate for Account 501
0.00
AccountBalance
Aggregate for Account 502
300.00
Command Handler
Command:
Transfer 100€ from
Simon Oberthür to Björn Senft
Event Store
Debit100€
Credit200€
…
Credit50€
Debit500€
Events
belonging to
Account 501
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft28
25. Event
Sourcing
Example: Bank Account
Domain Model
AccountBalance
Aggregate for Account 501
0.00
AccountBalance
Aggregate for Account 502
300.00
Command Handler
Command:
Event Store
Received100€from
Acc502
Debit100€
Credit200€
…
Credit50€
Debit500€
Events
belonging to
Account 501
Append Transfer 100€ from
Simon Oberthür to Björn Senft
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft29
26. Event
Sourcing
Example: Bank Account
Domain Model
AccountBalance
Aggregate for Account 501
100.00
AccountBalance
Aggregate for Account 502
200.00
Command Handler
Command:
Event Store
Received100€from
Acc502
Debit100€
Credit200€
…
Credit50€
Debit500€
Events
belonging to
Account 501
Query
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft30
27. Saving and
Restoring
Saving
• Create an event for every state
change of the object
• Persist this stream of events,
preserving event order
BankAccountCreated
Id: 501
Owner: Björn Senft
DepositPerformed
AccountId: 501
Amount: 20€
OwnerChanged
AccountId: 501
NewOwner: Simon Oberthür
WithdrawalPerformed
AccountId: 501
Amount: 10€16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft33
28. Saving and
Restoring
Saving Restoring
• Create an event for every state
change of the object
• Persist this stream of events,
preserving event order
• Subsequently apply the events
from the respective EventStream
to a "blank" object instance
BankAccountCreated
Id: 501
Owner: Björn Senft
DepositPerformed
AccountId: 501
Amount: 20€
OwnerChanged
AccountId: 501
NewOwner: Simon Oberthür
WithdrawalPerformed
AccountId: 501
Amount: 10€
BankAccount
Empty
apply to
BankAccount
Id: 501
Owner: Björn Senft
Balance: 0€
produces
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft34
29. Saving and
Restoring
Saving Restoring
• Create an event for every state
change of the object
• Persist this stream of events,
preserving event order
• Subsequently apply the events
from the respective EventStream
to a "blank" object instance
BankAccountCreated
Id: 501
Owner: Björn Senft
DepositPerformed
AccountId: 501
Amount: 20€
OwnerChanged
AccountId: 501
NewOwner: Simon Oberthür
WithdrawalPerformed
AccountId: 501
Amount: 10€
BankAccount
Id: 501
Owner: Björn Senft
Balance: 0€
BankAccount
Id: 501
Owner: Björn Senft
Balance: 20€
BankAccount
Empty
apply to
apply to
produces
produces
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft35
30. Saving and
Restoring
Saving Restoring
• Create an event for every state
change of the object
• Persist this stream of events,
preserving event order
• Subsequently apply the events
from the respective EventStream
to a "blank" object instance
BankAccountCreated
Id: 501
Owner: Björn Senft
DepositPerformed
AccountId: 501
Amount: 20€
OwnerChanged
AccountId: 501
NewOwner: Simon Oberthür
WithdrawalPerformed
AccountId: 501
Amount: 10€
BankAccount
Id: 501
Owner: Björn Senft
Balance: 0€
BankAccount
Id: 501
Owner: Björn Senft
Balance: 20€
BankAccount
Id: 501
Owner: Simon Oberthür
Balance: 20€
BankAccount
Empty
apply to
apply to
apply to
produces
produces
produces
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft36
31. Saving and
Restoring
Saving Restoring
• Create an event for every state
change of the object
• Persist this stream of events,
preserving event order
• Subsequently apply the events
from the respective EventStream
to a "blank" object instance
BankAccountCreated
Id: 501
Owner: Björn Senft
DepositPerformed
AccountId: 501
Amount: 20€
OwnerChanged
AccountId: 501
NewOwner: Simon Oberthür
WithdrawalPerformed
AccountId: 501
Amount: 10€
BankAccount
Id: 501
Owner: Björn Senft
Balance: 0€
BankAccount
Id: 501
Owner: Björn Senft
Balance: 20€
BankAccount
Id: 501
Owner: Simon Oberthür
Balance: 20€
BankAccount
Id: 501
Owner: Simon Oberthür
Balance: 10€
BankAccount
Empty
apply to
apply to
apply to
apply to
produces
produces
produces
produces
Deleting?
Retroactive Event! An event undoing something that happened in the past.
BankAccountClosed
reason
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft37
32. Pros and
Cons
General Advantages
• High Scalability
• Transparency as every change is recorded
• Deterministic error search
General Disadvantages
• High software development effort
• “Packaging up every change to an application as an
event is an interface style that not everyone is
comfortable with, and many find to be awkward” ?
• „Querying on a lot of events“
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft39
34. CQRS
Service
Interfaces
Read Side
Write Side
Event Store
Publishes Events after
they have been saved
Denormalized Read Store
Subscribes to Events
on the Write Side
Query
Append
events
Events
Query response
User views data
in the UI
User makes a
change in the UI
Command
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft41
35. Pros and
Cons
General Advantages
• High Scalability
• Optimal for SOA / Cloud Computing
• Read and Write access can scale indepently
• Split up development for teams
General Disadvantages
• High software development effort
• Needs a fitting infrastructure
• Transactions are challenging
• You can query before a command was executed
(Eventual Consistency)
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft42
38. ES + CQRS
for
experiments
Different versions at runtime
• Bounded contexts
• Parallel models
• Separation of read and write side
Logging
• ES stores every state change by default
• User interactions can directly be logged into ES
Microservices
• Lower complexity
• Easier change of requirements
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft45
39. Experiments
are not
feasible!
• Risk to change a running system is too high!
• Huge effort to host several alternatives!
• Experiments produce insights on which we can‘t react
fast enough!
• Our technology stack doesn‘t support your idea!
• Running experiments cost too much (e. g.
implementation, seperate logging, assign experiments
to users)!
• Experiments aren‘t mature and crash the whole system!
• We can support only one version of the API at once!
16.01.2018 Event Sourcing und CQRS für Experimentieren - Björn Senft46