Architecture
Event-Driven Architecture
Event-driven systems communicate through events β immutable records of things that happened. This decouples producers from consumers and enables reactive, scalable architectures.
- Events β Immutable facts about state changes
- Event Sourcing β Store events instead of current state
- CQRS β Separate read and write models
Event-driven architecture trades consistency for scalability and resilience.
What Is Event-Driven Architecture?
An architectural pattern where components communicate by producing and consuming events through a message broker.
DfEvent-Driven Architecture
Event-Driven Architecture (EDA) is a software design pattern where the flow of the program is determined by events. An event is an immutable record of a significant change in state. Components communicate asynchronously through a message broker, decoupling event producers from consumers.
DfEvent
An event is an immutable record of something that happened in the system. Events are named in past tense (OrderPlaced, PaymentProcessed) and contain all data needed by consumers. Once created, events cannot be modified or deleted.
Event Sourcing
DfEvent Sourcing
Event Sourcing stores the history of state changes as a sequence of events rather than storing only the current state. The current state is derived by replaying events. This provides a complete audit trail, enables time-travel debugging, and supports multiple read models.
Event sourcing is NOT the same as EDA. You can use events without event sourcing, and event sourcing doesn't require a message broker. However, they complement each other well in distributed systems.
Event Store
State Derivation
Here,
- =Application state at time t
- =Starting state (usually empty)
- =Sequence of events from start to time t
Event Sourcing for Orders
Events:
- OrderCreated { order_id: 123, items: [...], user_id: 456 }
- ItemAdded { order_id: 123, item: "widget", qty: 2 }
- PaymentReceived { order_id: 123, amount: 29.99 }
- OrderShipped { order_id: 123, tracking: "XYZ789" }
Current state = replay all events for order 123. To get state at any point in time, replay events up to that point.
CQRS
Separating read and write models for independent optimization.
DfCQRS
Command Query Responsibility Segregation (CQRS) separates the data model for reads (queries) from writes (commands). The write side uses a normalized model optimized for consistency; the read side uses denormalized views optimized for query performance. Events propagate changes from write to read models.
Saga Pattern
Managing distributed transactions across services.
DfSaga Pattern
A saga is a sequence of local transactions. Each step publishes an event that triggers the next step. If a step fails, compensating transactions undo previous steps. Sagas provide eventual consistency without distributed locks.
Choreography vs Orchestration
| Approach | Description | Pros | Cons |
|---|---|---|---|
| Choreography | Each service listens for events and reacts | Loose coupling, simple | Hard to track flow, cyclic deps |
| Orchestration | Central coordinator directs the flow | Clear flow, easy to modify | Single point of failure, tight coupling |
Sagas do not provide isolation. Intermediate states are visible to other transactions. Use semantic locks (reserved, pending, confirmed) or pessimistic concurrency control to mitigate.
Practice Exercises
-
Design: Design an event-driven architecture for an e-commerce order flow: order placement, payment, inventory reservation, shipping. Include event schemas and saga steps.
-
Event Sourcing: Implement event sourcing for a bank account. Events: AccountCreated, Deposited, Withdrawn, Transferred. Derive current balance by replaying events.
-
CQRS: Design CQRS for a social media feed. The write side handles posts; the read side materializes personalized feeds. How do you handle fan-out?
-
Trade-offs: Compare event-driven architecture with synchronous REST for a ride-sharing app. Which components benefit from events? Which should remain synchronous?
Key Takeaways:
- Event-driven architecture decouples producers and consumers via message brokers
- Event sourcing stores state changes as immutable events, not current state
- CQRS separates read and write models for independent optimization
- Sagas manage distributed transactions through compensating actions
- Events provide audit trails, enable time-travel, and support multiple read models
- Trade consistency for scalability and resilience in distributed systems
What to Learn Next
-> Service Mesh Envoy, Istio, and sidecar proxy patterns.
-> Data Replication Leader-follower, multi-leader, and conflict resolution.
-> Distributed Consensus Raft, Paxos, and leader election algorithms.
-> Containerization Docker, Kubernetes, and pod scheduling.
-> CI/CD Pipelines Continuous integration and deployment strategies.
-> Observability Logging, metrics, tracing, and monitoring.