8. CQS
• Command–query separation
• every method should either be a command
that performs an action
• or a query that returns data to the caller
• but not both = no side effects
• Asking a question should not change the
answer.
11. Why CQRS?
• Queries
(READ PERFORMANCE !)
1. can be routed to
•
•
fast in-memory
non-transactional databases
12. Operation
L1 cache reference
Branch mispredict
L2 cache reference
Mutex lock/unlock
Main memory reference
Latency
0.5 ns
5 ns
7 ns
25 ns
100 ns
Compress 1K bytes w/ cheap algorithm
3,000 ns
Send 2K bytes over 1 Gbps network
20,000 ns
Read 1 MB sequentially from memory
250,000 ns = 0.25ms
Round trip within same datacenter
500,000 ns
Disk seek
10,000,000 ns
Read 1 MB sequentially from disk
20,000,000 ns = 20ms (-80x)
Send packet CA->Netherlands->CA
150,000,000 ns
13. Why CQRS?
• Queries
(READ PERFORMANCE !)
2. can query well prepared denormalised datasets
(without relations, no JOINS’s – just raw data)
DATA DENORMALIZATION !!
Imagine ideal dataset you want to receive in
your application use case
… and prepare it in background.
14. Why CQRS?
• Queries
(READ PERFORMANCE !)
3. warehouse approach:
can select aggregated datasets/tables
for e.x. report tables that contains numbers
(metrics) groupped by the domain (dimension)
SELECT SUM(price), SUM(transactions)
FROM acc_by_day
WHERE g_year = 2013 AND g_month = 8
16. Why CQRS?
• Queries
(READ PERFORMANCE !)
1. can be routed to fast in-memory nontransactional databases
2. can query well prepared datasets
(without relations)
3. warehouse purpose:
can select aggregates datasets/tables
for e.x. report tables that contains numbers
(metrics) groupped by the domain (dimension)
17. Commands
• Commands are imperatives
• Produces Events
• Requests for the system
to perform a task or action
18. Events
• Produced by Commands
• Commands publishes
– one-way
– asynchronous messages
– that are published to multiple recipients
• Events are descriptions of actions to be
happened (for e.x. item’s description changed)
• Events are handeled by handlers
to perform some actions
19. Event handlers
• Subscribes for Events occurence
• Performs some actions:
– Persists new state of object
– Updates aggregates
20. Processing
• Events can be catched by handlers
in two ways:
– Synchronously
(immediately after perform in the same thread or
sub-thread)
like: myListener.onSthChanged(Event e)
– Asynchronously
(added to queued system to futher process)
messageBroker.publish(Event e)
21. Embracing eventual consistency
• Database systems:
– atomicity
(the action is one trasactional operation),
– consistency,
– isolation
(other processes cannot access local variables),
– durability
(all data is persisted)
• (ACID) properties of transactions
22. Data consistency
• Data on the read side will be eventually
consistent with the data on the write side
• When you query data, it may be out of date
• Don’t say: data are not consistent –
that sounds bad …
data is temporarly out of date… - better
23. Data consistency
• You can deal with consistency by using
distributed transactions
• Distributed transaction = performance issues
with synchronization
• The faster side waits to another, but is ready
27. Data consistency
• That’s why use queues – write performance
• Messaging and CQRS:
– Commands (one recever)
– Events (many receivers)
28. CQRS messaging problems
Consider system bottlenecks:
versioning
handshake and
persistence
•
•
•
•
Duplicated messages
Unordered messages
Lost messages
Unprocessed messages
29. We need messaging system
• Simple queue
• Work queues
(one consumer)
• Publish/Subscribe
(many consumers)
30. RabbitMQ
• Open source message broker
• written in the Erlang
• Implements the Advanced Message Queuing
Protocol (AMQP)
– also: Apache ActiveMQ, Windows Azure Service Bus
31. RabbitMQ
• Decopules publishers and consumers
Producer
Consumer
• Queueing for later delivery
• Load balancing (round-robin) and scalability
32. RabbitMQ reliability
• Round-robin dispatching
• Message acknowledgment (after processing)
– message had been received, processed and that
RabbitMQ is free to delete it
– no message timeouts - RabbitMQ will redeliver
the message only when the worker connection
dies
33. RabbitMQ reliability
• Acknowledgments are turned on by default
• You have to disable ack and send
programmatically!
$ sudo rabbitmqctl list_queues name
messages_ready
messages_unacknowledged
34. RabbitMQ reliability
• Durable Queues
1. Make sure that RabbitMQ will never lose
our queue:
durable = true
2. Send message in persistent mode:
delivery_mode = 2
# make message persistent
35. RabbitMQ + Node.js
• https://github.com/postwait/node-amqp
$ npm install amqp
• I have reported issue in releasing, so include in
your packages.json to have the newest
version directly from github tarball:
"dependencies": {
"amqp": "https://github.com/postwait/node-amqp/tarball/master"
}