Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CQRS: Synchronizing the Write and Read databases

Tags:

cqrs

Can anyone please give me some direction in regards to various ways to synchronize the Write and Read databases?

What are different technologies out there, and how do you evaluate each, in terms of realiability, performance, cost to implement, etc.

like image 958
Mosh Avatar asked Jul 13 '10 07:07

Mosh


People also ask

How does CQRS pattern work?

CQRS separates reads and writes into different models, using commands to update data, and queries to read data. Commands should be task-based, rather than data centric. ("Book hotel room", not "set ReservationStatus to Reserved").

What is CQRS pattern in Microservices?

CQRS is one of the important pattern when querying between microservices. We can use CQRS design pattern in order to avoid complex queries to get rid of inefficient joins. CQRS stands for Command and Query Responsibility Segregation. Basically this pattern separates read and update operations for a database.


3 Answers

Query model need not be consistent.. it needs to be eventually consistent. Query model is also the view model, i.e. tables are already joined as per requirement of user interface. So you can use even an in memory cache, or like Redis.
Command side is like command objects which contain all relevant information to update database. These objects may fill up a messaging queue. The command objects are processed by a command processor which transactionally updates the query cache and the write database. The write database can be an RDBMS.. but as is apparent, should be write optimized like MongoDB.
You can update read database via a messaging system too.
Some good messaging systems for this purpose are RabbitMQ and 0MQ.

like image 108
Apurva Singh Avatar answered Oct 17 '22 01:10

Apurva Singh


Typically in CQRS, the write DB is used to store transitional data for long running processes (sagas). If you are synchronizing the read and write DB (I'm assuming you mean both ways), you might be doing something wrong.

For a long running process where a service expects multiple messages, it needs a way to temporary store data before the all the messages arrives. An example of this is customer registration where an approval from manager, which takes a week to process, is required. The service needs a way to temporarily store the customer information before the approval arrives. This is where the write DB is used to store this piece of temporary data. Note that before the customer is approved, nothing is written to the read DB yet.

When the approval finally arrives, the service will take the customer information from the write DB, complete the registration process and write it to the read DB. At this time, the temporary customer information in the write DB has done its job and can be removed from the write DB. Notice that there isn't any two-way sync'ing involved.

For simpler process such as change customer first name, the change can be written to the read DB right away. Writing to the write DB is not required because there is no temporary data in this case.

like image 30
stung Avatar answered Oct 17 '22 00:10

stung


If you, like me see the read store as the db that the Query service use (and its denormalized) and the write db as the database where the Domain events are stored , then if you need to Synch them to a particular moment then what you can do is just replay the events that you have stored. In the case you want to be as up to date as possible then you need not to restrict by version

If you are using CQRS, then probably you will have a repository that looks somewhat like this

    public interface IRepository<T> where T : AggregateRoot, new()
    {
        void Save(AggregateRoot aggregate, int expectedVersion);
        T GetById(Guid id);
        T GetById(Guid id, int version);
    }

Hope this helps Cheers

like image 40
roundcrisis Avatar answered Oct 16 '22 23:10

roundcrisis