Upload
dennis-doomen
View
141
Download
3
Tags:
Embed Size (px)
DESCRIPTION
I've recently got the opportunity to work on a large enterprise-class system that needs to be deployed on multiple occasionally connected oil platforms and boats. Already the system's architecture was based on the Command Query Separation principles, this gave us a completely new challenge. After several months of looking at alternatives, we decided to go the Event Sourcing direction. In this in-depth session, I'd like you to learn the many alternatives we observed, the pros and cons, and the technical details of our final solution in which we use EventStore 3.0 and elements of NCQRS and Lokad.CQRS to synchronize systems over unreliable connections in a very efficient way.
Citation preview
© 2014 Aviva Solutions 10 april 2023
Occassionally Connected ApplicationsWith Event Sourcing
Dennis Doomen
© 2014 Aviva Solutions 10 april 2023Dennis Doomen
About Me• Principal Consultant• 17 years in IT• C++ origins but C# since 2001• Specialties
• .NET• Architecture• Scrum/Kanban/XP• ALM
• Speaker• Public initiatives
• C# Coding Guidelines• Fluent Assertions
• Internet• www.dennisdoomen.net• DZone MVB• @ddoomen
© 2014 Aviva Solutions 10 april 2023
Contents• What we tried to solve• Our options• What we choose for• Design Challenges• Scalability Challenges• Architectural Challenges• Concurrency Challenges• Future?
© 2014 Aviva Solutions 10 april 2023
What we tried to solve
© 2014 Aviva Solutions 10 april 2023
Central Farm
Seaborn Servers
Decentralized Servers
Mobile Clients
Intermittent Satellite
Connection
High-Latency
LAN
3G (w/o attachments)
WLAN (attachments)
Only synchronize what is relevant!
>100
XCopy RDBMS
© 2014 Aviva Solutions 10 april 2023
What we had
Command Service
Commands
Domain Model
Repositories
Domain Services
SQL / Oracle
Service Agents
Web Application
Backoffice Systems
Command HandlersQuery Processor
Repositories
Projections
Query Handlers
Patterns & Principles• Domain Driven Design• CQRS• Repository Abstraction• TDD/BDD• SOLID
Framework & Libraries• NHibernate• Autofac• ASP.NET WebForms / MVC• SQLite
Queries
© 2014 Aviva Solutions 10 april 2023
Our options1. SQL Server Replication2. Command Synchronization3. Aggregate Serialization4. RavenDB 5. Event Sourcing
© 2014 Aviva Solutions 10 april 2023
1. SQL Server Replication
Automatic reconnectsProven technology
Automatic schema updatesDevelopment can be outsourced
Synchronization over HTTP
Only SQL Server (Express)Filtering is limited
Affects client infrastructureNo real-world examplesUnsure about limitationsRequires SQL expertize.
Difficult to diagnose issues during development
© 2014 Aviva Solutions 10 april 2023
2. Command Synchronization
Supports any databaseNo special deployments requirements
Potentially unresolvable out-of-sync issue
Requires bypassing business rulesCommand != actual changeLimited filtering possibilities
Custom serializationSeparate queue of commands
© 2014 Aviva Solutions 10 april 2023
3. Aggregate Serialization
Supports any databaseNo special deployments requirementsDoesn’t interfere with business rules
No out-of-sync issues
Requires specialized code per aggregate
Needs an enforced order of synchronization.
Payload is not optimizedRequires a lot of querying and change
tracking
© 2014 Aviva Solutions 10 april 2023
4. RavenDB
Reduces complexitySmart reconnects
Synchronization built-inArchiving built-inBuilt-in cachingVery scalable
Improves productivityImproves query performance
Lucene based
Acceptance by enterprise clientsNew querying (map/reduce) concepts
Limited track record
© 2014 Aviva Solutions 10 april 2023
Web Application
Command Service
Query Processor
ChangeUserEmailHandler
User Aggregate
Domain UOW
UserProjector
Projections UOW
Query Handler
Read DB Write DB
Submit ChangeUserEmailCommandExecute query
Get<TAggregateRoot>(key, version)
LINQ, HQL, SQL
Commits
Invoke method
DAO
Load(events)
Apply
Get changes
Dispatcher Commit
Handle(UserEmailChangedEvent)
Submit changes
Event Sourcing
© 2014 Aviva Solutions 10 april 2023
5. Event Sourcing
Transparent to clientsWorks with any SQL/No-SQL DB
Can improve performanceAdvance conflict resolution
Natural unit of synchronizationCan be very scalable
Lots of new conceptsBig impact on domain model
Synchronization must be custom-builtLots of unforeseen challenges
© 2014 Aviva Solutions 10 april 2023
What we chose for
© 2014 Aviva Solutions 10 april 2023
The Revised Architecture
Command Service
Commands
Domain Model
Domain Repository
Domain Services
Event Store
Service Agents
Web Application
Backoffice Systems
Command Handlers
Query Store
Query Processor
Projection Repositories
Queries
Projectors
Events
DispatcherEvents
Projections
Query Handler
© 2014 Aviva Solutions 10 april 2023
Advantages• Optimized projections• Projections = cache -> rebuild anytime• Reporting node• Intrinsic auditing• Supports temporal projections
© 2014 Aviva Solutions 10 april 2023
Changes
1
2
3
6297
6298
6298
Blobs
Query Data
Documents
Groups
Users
Objects
Folders
User Interface
Changes Queries
Attachments,Images, etcChanges
1
2
3
6299
6300
6301
Blobs
Query Data
Documents
Groups
Users
Objects
Folders
User Interface
ChangesQueries
Attachments,Images, etc
Primary Node Laptop / Secondary Node
Check-out / Check-in
WIFI/LAN/3G
WIFI/LAN
Just changes ownership of an aggregate and
forces synchronization
Each aggregate is owned by a node to prevent functional
conflictsCan be rebuild from the changes table at any point
in time
Optimized for querying
SOAP/WS-*
SOAP/WS-*
HTTPS-REST
E.g. UserPasswordChanged, DocumentSigned,
TitleChanged, RoleRevoked
Contains a subset of the master
Synchronization Overview
© 2014 Aviva Solutions 10 april 2023
Design Challenges
© 2014 Aviva Solutions 10 april 2023
NEventStore vs Lokad.CQRS vs NCQRS
User Aggregate
EventStoreDataMapper
ChangeEmail()
NEventStore 3
Commits
User State
Apply(EmailChangedEvent)
GetAggregateRoot(key)
Domain Unit Of Work
Caller
Load(key)
Open Stream(guid)
new User()
Load(events)
OnEventApplied()
SubmitChangesWrite Into Stream Per Aggregate
© 2014 Aviva Solutions 10 april 2023
Immediate vs Eventual Consistency
Projections Commits
EventStoreDataMapper
NEventStore 3
Projector
NHibernate
Dispatched Event
Submit Changes
Transactional Boundary Transactional Boundary
Queries
© 2014 Aviva Solutions 10 april 2023
Event Versioning
Event V1 Event V2
Some Event
Combined Event
Other Event
Combined Event
Separate Event
Separate Event
© 2014 Aviva Solutions 10 april 2023
Other Challenges• No direct AR dependencies• Granularity of events• Domain Events as facts, not triggers
© 2014 Aviva Solutions 10 april 2023
Scalability Issues
© 2014 Aviva Solutions 10 april 2023
Scalability Limitations• Commits table grows and gets slower• No partitioning of global data• Single point of failure• Upgrades take too much time
© 2014 Aviva Solutions 10 april 2023
Changes
1
2
3
6297
6298
6299
Blobs
Query Data
Documents
Groups
Users
Objects
Folders
Changes
1
2
3
6299
6300
6301
Blobs
Query Data
Documents
Groups
Users
Objects
Folders
Version 1.0 Version 3.0
Schema 1.0
Pass 1= no down time
Out-of-place migration
Schema 3.0
Pass 2= down time
Setup
Upconverts commits, blobs, etc
© 2014 Aviva Solutions 10 april 2023
Multi-Tenant Scaling
Integration NodeReporting
Server
Node(owns tenants 1 & 2)
Node(owns tenants 3 & 4)
Node(owns tenants 5 & 6)
Node (failover for tenants 5 & 6)
Node(owns tenants 9 & 10)
Node(owns ref. data &
node config)
Node (uses tenants 1 & 2, owns tenant 11)
Node(uses tenants 1 & 11)
Node(uses tenants 3 & 5)
Node(uses tenants 5 & 10)
Connects to back-office systems Specific reporting
representations of the data
Owns global data and ownership configuration
Decentralized node
© 2014 Aviva Solutions 10 april 2023
Architectural Issues
© 2014 Aviva Solutions 10 april 2023
Limiting Constraints• Recovery in web farm• Selective rebuilding of projections• No asynchronous dispatching• Relational database is bottleneck during load
balancing• Network overhead web->database
© 2014 Aviva Solutions 10 april 2023
Web Site Web Site
Load Balancer
RDBMS
Projections
RDBMS
Commits
Worker Thread
Worker Thread
?
Application Tier
Database Tier
First Attempt
© 2014 Aviva Solutions 10 april 2023
Web Site Web Site
Load Balancer
RDBMS
Projections
RDBMS
Commits
Worker Thread
Worker Thread
RDBMS
Projections
Application Tier
Database Tier
Second Attempt
© 2014 Aviva Solutions 10 april 2023
Web Site Web Site
Load Balancer
RavenDB
Projections
RDBMS
Commits
Worker Thread
Worker Thread
RavenDB
Projections
Application Tier
Database Tier
Final Attempt
© 2014 Aviva Solutions 10 april 2023
RavenDBAdvantages• No migrations needed• No more column length problems• Faster• Less SQL Server load• More scalable• Dynamic Indexing • Keyboard/faceted search w/
Lucene• Concious decision on
asynchronicity
Disadvantages• New technology, new concepts• No LINQ• Async indexes• Requires rewrite of all projectors and queries
© 2014 Aviva Solutions 10 april 2023
Front-End Server
RavenDB
Projections
Commits
Application Tier
Database Tier
Web Site WCF Services
Job Scheduler
Worker Thread ???
?
© 2014 Aviva Solutions 10 april 2023
Front-End Server
RavenDB
Projections
Commits
Application Tier
Database Tier
Web Site
WCF Services
Job SchedulerWorker Thread
/queries/{query}
© 2014 Aviva Solutions 10 april 2023
Web Site
RavenDB
EventStore
Component RepositoryMain Repository
QueryHost Raven
QueryHost
QueryHost Client
Module Module
OWIN Startup
Projectors Projectors
QueriesQueries
Query Handlers
Query Handlers HTTP (network or memory)
Thread Pool
Query
Commit
/queries/{query}
QueryHost RavenDB
Owin
WebAPI 2
NEventStore
Katana
AutofacDurable Commit Dispatcher
Querying Controller
Query Host Settings
RavenSession Checkpoint Store
HTTP-based QueryProcessor Interfaces
© 2014 Aviva Solutions 10 april 2023
Concurrency Issues
© 2014 Aviva Solutions 10 april 2023
StreamId: User-Dedo, Rev: 5
Primary Node Laptop / Secondary Node
Event Merging
StreamId: User-Dedo, Rev: 4
StreamId: User-Dedo, Rev: 3
UserCreatedEvent
GrantedRoleEvent
PhoneNumberAddedEvent
GrantedRoleEvent
PasswordChangedEvent
StreamId: User-Dedo, Rev: 4
StreamId: User-Dedo, Rev: 3
UserCreatedEvent
GrantedRoleEvent
PhoneNumberAddedEvent
PasswordChangedEvent
StreamId: User-Dedo, Rev: 5
RoleRevokedEvent
Last Sync Point
StreamId: User-Dedo, Rev: 6
GrantedRoleEvent
Time
StreamId: User-Dedo, Rev: 7
PasswordChangedEvent
StreamId: User-Dedo, Rev: 6
RoleRevokedEvent
StreamId: User-Dedo
PasswordChangedEvent
© 2014 Aviva Solutions 10 april 2023
Future?
© 2014 Aviva Solutions 10 april 2023
Opportunities• In-memory projections• Gossip-based detection• ATOM feeds
© 2014 Aviva Solutions 10 april 2023
Reading Material• NEventStore on GitHub• Domain Events by Udi Dahan• Event Versioning by Rinat Abdullin• Effective Aggregate Design by Vaughn Vernon• NHibernate vs Entity Framework in DDD by me…• DomainDrivenDesign.org• RAFT, a distributed consensus protocol• Cedar by Damian Hickey