The document summarizes Andrea Saltarello's presentation on implementing CQRS and event sourcing patterns on Azure. The presentation included a recap of CQRS and event sourcing, demonstrations of aggregates, handlers and read models, and discussions of deployment options on Azure including n-tiered and full-stack approaches. It also covered technology considerations and options for event buses, event stores and economic comparisons of Azure computing services.
Azure tales: a real world CQRS and ES Deep Dive - Andrea Saltarello
1. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
Azure tales: a real world CQRS and
ES Deep Dive
Andrea Saltarello
Solution Architect @ Managed Designs
https://twitter.com/andysal74
https://github.com/andysal
3. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
Andrea Saltarello
• Solution Architect @ Managed
Designs
• Microsoft .NET MVP since 2003
• Microsoft Regional Director
• Author, along with Dino, of .NET:
Architecting Applications for the
Enterprise, di Microsoft Press
• Basically, a software architect eager
to write code ☺
7. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
Not the way to implement Event Sourcing, but a
working way to do it nonetheless
Demo app available on Github (GPL3): it is a real open
source project of which my company sells
customizations
There’s no silver bullet
10. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
It really became clear to me in the last couple of years that we
need a new building block and that is the Domain Event.
[Eric Evans]
An event is something that has happened in the past.
[Greg Young]
A domain event … captures the memory of something
interesting which affects the domain
[Martin Fowler]
11. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
Instead of focusing on a system’s last known
state, we might note down every occurring
event: this way, we would be able to (re)build
the state the system was in at any point in time
just replaying those events
To cut a long story short: we’d end up
recording an event stream
Event Sourcing in a nutshell
JobOrderStarted InvoiceIssuedJobOrderExtended JobOrderCompleted
12. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
The (immutable) composition of:
• A (meaningful) name
• (Typed) Attributes
What’s an event, anyway?
InvoiceIssued
DateOfIssue
Customer
Price
ProjectStarted
DateOfStart
ProjectId
ProjectCompleted
DateOfCompletion
ProjectId
ProjectRegistered
DateOfRegistration
DateOfEstimatedCompletion
ProjectId
CustomerId
Price
14. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
Still, my users are more interested in knowing a job
order’s balance or whether an invoice has been paid.
(cit.)
That is, we need a way to produce an entity state
Event Stream vs. «My application»
15. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
DDD’s Aggregates provide a convenient way to encapsulate event
management
Aggregate: A collection of objects that are bound together by a root
entity, otherwise known as an aggregate root. The aggregate root
guarantees the consistency of changes being made within the
aggregate.
[Wikipedia]
An aggregate is responsible for:
• encapsulating business logic pertaining to an “entity”
• generating events to have them available for saving
• replaying events in order to rebuild a specific state
Event Sourcing <3 DDD
17. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
var aggr = repository.GetById<TAggr>(id); //Triggers [time travelling] event
replay
aggr.DoSomething(); //Biz logic + events
repository.Save(aggr); //Updates the event stream
Repository: Mediates between the domain and data mapping layers using a
collection-like interface for accessing domain objects. [DDD]
Aggregates vs. Events vs. Repos
19. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
Still², my users are more interested in knowing a job
order’s balance or whether an invoice has been paid.
Quickly.
Ways to achieve that:
• Snapshots can help
• CQRS to the rescue: let’s have a database storing the usual «last
known system state» and use it as a read model
Event Stream vs. «My application»
20. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
Acronym for Command Query Responsibility
Segregation
Basically, ad hoc application stacks for either “writing”
or reading:
• “Command” stack writes events and snapshots
• “Read” stack reads from eventually consistent, reading
purposes optimized database(s)
Enter CQRS
22. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
1. Application sends a command to the system
2. Command execution might alter the system’s state and
then raise events to state success/failure
3. Events are notified to interested subscribers (a.k.a.
handlers), such as:
• Workflow managers (a.k.a. «Sagas») which could execute more
commands
• Denormalizers, which will update the read model database
Note: command/event dispatch/execution will usually be
managed by a Mediator («bus»)
CQRS/ES in a nutshell
23. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
Application
Layer
Snapshots
Event store
Read stack
Domain Layer
Ad-hoc DBHandlers
Command Event Data
Handlers
Model ServicesB
U
S
CQRS/ES at a glance
26. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
Azure <3 CQRS: n-tiered
Back-endFront-end
Application
Layer
Snapshots
Event store
Read stack
Domain Layer
Ad-hoc DBHandlers
Command Event Data
Handlers
Model Services
A
S
B
27. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
Front end:
• VM
• Web role
• App Service
• Docker
Back end:
• Worker role
• Service Fabric
• Docker
N-tiered deploy
28. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
Azure <3 CQRS: full stack
App Service
Application
Layer
Snapshots
Event store
Read stack
Domain Layer
Ad-hoc DBHandlers
Command Event Data
Handlers
Model Services
A
S
B
30. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
A fine-grained deploy allows each “component” to be:
• Evolved
• Deployed
• Configured (e.g.: scaled)
Independently, thus having each one only consuming
the resources it really needs but it means having more
moving parts to manage
N-tiered vs. Full stack
32. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
App Service Cloud Services Docker Service Fabric VM
PROs:
• PaaS
PROs:
• PaaS
PROs
• Deploy
• Scaling*
• Documentation/samples
PROs:
• Fault tolerance
• Load balancing
• Deploy
PROs
• (Usually) cheapest
monthly bill
• No new skiils needed
• Unparalled option set
CONs:
• .NET 4.5.1 only(*)
CONs: (?)
• Need for an orchestrator
CONs:
• Ad-hoc SDK
CONs:
• Management
Azure Compute smackdown
33. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
A 2 cores, 3.5 GB RAM, 60 GB disk compute unit costs:
• 75,92 EUR/month as a VM
• 94,11 EUR/month as an AppService
• 100,39 EUR/month as a Cloud Service (*)
• 338,80** - 564,47*** EUR/month as a Service Fabric
cluster
* 490Gb disk
**3 nodes
***5 nodes
From a billing perspective
34. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
An effective CQRS/ES implementation usually relies on
2 structural pillars:
• A mediator bus
• An event store
Well come on and let me know…
Should I stay build or should I go (shopping)? (demi
quote)
On a technology side…
35. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
Rebus.net:
• is an open source, production tested bus for .NET. Source code is available
on Github, but usually Nuget packages will do.
• provides much-needed features such as:
– Fault tolerance
– Scalability
– Events’ scheduling
– Easy migration from on-premises to cloud
• requires:
– a transport protocol (e.g.: MSMQ, RabbitMQ, Azure Service Bus, Amazon Sqs, ...)
– an IoC container (e.g.: Autofac, Ninject, .NET Core ServiceProvider, StructureMap,
Unity, Windsor...)
– a storage (e.g.: MongoDB, RavenDb, SQL Server, ...)
Enter Rebus.net
37. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
MementoFX NEventStore
https://www.nuget.org/packages?q=MementoFx
• FOSS
• DDD/ES stack
• Time travelling
• Alternative timelines
https://www.nuget.org/packages?q=NEventStore
• FOSS
• Event Store API only
• “CommonDomain” package available to support DDD
• Wide community + Slack channel
CQRS Application Frameworks
38. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
CosmosDB mLab VM
PROS:
• Multiple APIs (e.g.: DocumentDB,
MongoDB)
• PaaS
• Scalability/Georedundancy
PROS:
• PaaS
• Large ecosystem
PROS:
• Unparalleled configuration
options
CONS:
• Billing
CONS:
• Few instance sizes
CONS:
• Management
Event Store: a couple of options
39. @ITCAMPRO #ITCAMP17Community Conference for IT Professionals
• A CosmosDB database is billed on a per-collection basis, with
a 1 GB, 400 RU/sec collection costing 20.08 EUR/month
• A 3 “A2” VM MongoDB Linux cluster costs 146,82 EUR/month
(but we’d have to manage it)
• mLab’s dedicated cluster options:
From a Billing perspective
Size RAM Disk Monthly price
M1 1.7 GB 40 GB $200
M2 3.5 GB 60 GB $400
M3 7 GB 120 GB $800
M4 14 GB 240 GB $1,320
M5 28 GB 480 GB $2,450
M6 56 GB 700 GB $4,280