CQRS Manager for Distributed Reactive Services (herein abbreviated CMDR) is a component that provides the organizing principle in a specific architecture for building real-time, event-driven APIs with complex business logic at large scale. This architecture incorporates several well-known patterns:
- CQRS (Command Query Responsibility Segregation), the separation of the write and read paths in an application
- Event Sourcing, the modeling of state by capturing all domain events
- Immutable Log-centric, Using an append-only log of immutable values to capture domain events
- Reactive Responsive, Resilient, Elastic, and Message Driven. Discrete components react to messages (commands and events) independently, with low latency, and in a fault-tolerant way.
The combination of the above ideas has the potential to solve many of the thorny problems in existing service architectures.
Many APIs and services are architected something like this:
This architecture is problematic in several ways:
In contrast, the CMDR architecture seeks to:
CMDR provides web interfaces to handle incoming writes/commands, performs basic structural validation, and then writes them down to the commands topic in the log (Kafka for now, with support for other distributed log systems planned). See the data contract docs for more information on the specific data definition of the terms "command" and "event".
The application's own processes take over from there, first processing the incoming commands from the log, determining how to handle them, and then emitting one or more events to the event topic in the log. This command processor is a special case, and each command should only be handled by a single command processor.
Downstream event processors are a bit different, as many event processors can react to the same set of events, and can emit zero or more events in response to those events.
Some of these events will cause side effects of some kind, such as writing to a database. Most distributed log systems (like Kafka) provide at-least-once message processing semantics, so event processors should be idempotent in terms of side-effects.
- Rich Hickey's talks on the Value of Values and the Language of the System
- Datomic's architecture
- Martin Kleppman's talks and writings
- Jay Kreps article on the Log as the unifying abstraction in distributed systems
- Neha Narkhede's blog post on the connection between CQRS, Event Sourcing, Stream Processing, and Kafka
- Bobby Calderwood's Strange Loop 2016 talk