CQRS

5,037 views
4,697 views

Published on

Published in: Technology

CQRS

  1. 1. CQRS Command Query Responsibility Segregation Piotr Pelczar me@athlan.pl
  2. 2. CQRS • Greg Young • different model to update information • than the model you use to read information • http://martinfowler.com/bliki/CQRS.html
  3. 3. CQRS is…
  4. 4. CQRS is… NOT the design pattern
  5. 5. CQRS is… architecture?
  6. 6. CQRS is… architecture? no i should say
  7. 7. CQRS is… architectural pattern
  8. 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.
  9. 9. Basic terms • Queries – Read models • Commands – Write models
  10. 10. CQRS • Queries – Read models, two-way • Commands – Write models, one-way http://berb.github.io/diploma-thesis/community/091_archtrends.html
  11. 11. Why CQRS? • Queries (READ PERFORMANCE !) 1. can be routed to • • fast in-memory non-transactional databases
  12. 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. 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. 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
  15. 15. Why CQRS? SELECT SUM(price), SUM(transactions) FROM acc_by_day WHERE g_year = 2013 AND g_month = 8 g_year g_month g_day price transactions 2013 08 11 7839 12 2013 08 12 12897 16 2013 08 13 5326 10 2013 08 14 2357 5 2013 08 15 3687 6 2013 08 16 5478 11
  16. 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. 17. Commands • Commands are imperatives • Produces Events • Requests for the system to perform a task or action
  18. 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. 19. Event handlers • Subscribes for Events occurence • Performs some actions: – Persists new state of object – Updates aggregates
  20. 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. 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. 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. 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
  24. 24. http://msdn.microsoft.com/en-us/library/jj591577.aspx
  25. 25. Data consistency • Distributed transaction = performance issues with synchronization • The faster side waits to another, unless it is ready
  26. 26. http://msdn.microsoft.com/en-us/library/jj591577.aspx
  27. 27. Data consistency • That’s why use queues – write performance • Messaging and CQRS: – Commands (one recever) – Events (many receivers)
  28. 28. CQRS messaging problems Consider system bottlenecks: versioning handshake and persistence • • • • Duplicated messages Unordered messages Lost messages Unprocessed messages
  29. 29. We need messaging system • Simple queue • Work queues (one consumer) • Publish/Subscribe (many consumers)
  30. 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. 31. RabbitMQ • Decopules publishers and consumers Producer Consumer • Queueing for later delivery • Load balancing (round-robin) and scalability
  32. 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. 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. 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. 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" }
  36. 36. RabbitMQ + Node.js Examples…
  37. 37. CQRS in Grails • Install plugins: – JMS – ActiveMQ • In your BuildConfig.groovy plugins { compile ":jms:1.2", compile ":activemq:0.4.1" // mvn }
  38. 38. CQRS in Grails Examples…
  39. 39. NCQRS (.NET) • Framework for .NET – command handling, – domain modeling, – event sourcing • Provides interfaces
  40. 40. NCQRS (.NET) Examples…
  41. 41. Literature • http://msdn.microsoft.com/en-us/library/jj554200.aspx • https://github.com/ncqrs/ncqrs
  42. 42. Literature • http://www.slideshare.net/rabbitmq/amqp-and-rabbitmq • http://www.udidahan.com/2011/10/02/why-you-should-beusing-cqrs-almost-everywhere%E2%80%A6/ • http://simon-says-architecture.com/tag/cqrs/
  43. 43. CQRS Q&A? http://slideshare.net/piotrpelczar/cqrs Piotr Pelczar me@athlan.pl

×