DANGER! The water is deep, let uncle come — talk about the separation of power and responsibility model of command query (cqrs)

Time:2021-11-23

Many years ago, when I was young, my skills were like fish in water, and I even wanted to be a front-line programmer all my life.

But I have two small wishes to achieve: one is to make more money; The other is to have more initiative in the selection of technology stack and architecture of the project.

I made more money because I just got married and had my own family planning, so I had a strong desire to make money.

The reason why I wanted to have more technical initiative was that the leaders appreciated me at that time. Some things were gradually delegated to me. I tasted the sweetness, so I also had some small ambitions.

At that time, the leader gave me a very important opportunity in my career.

At that time, the advertising alliance was in full swing. The company also wanted to participate in it, so it decided to build an advertising platform from scratch.

And I happen to have some similar development experience, and things are reliable. Therefore, the leaders want me to be the technical director of this system.

If I can do a good job in the system, it is definitely an opportunity for me to prove myself, which is good for achieving my two little wishes in the future. It’s very tempting for me.

But when God opens a door for you, he always closes a window for you. Not only did my leader take a fancy to this opportunity, but also the boss of another department took a fancy to it at that time.

As a last resort, it was discussed at a high-level meeting. The result of discussion is to learn from the practices of other companies and internal competition.

Each of the two departments will build a platform, and then each will operate online for a while. Whoever does well will get the opportunity of the company’s full investment.

Well, opportunity turns into adventure. But at this time, I can’t flinch. Once I retreat, it will affect and appreciate my leadership, and my development in the company will be seriously hindered in the future, so I can only rush.

In order to win this competition, I also communicated with the product leader of this system for a long time. Finally, two goals have been set:

1. The system must have as many functions as possible, especially for relevant business personnel.

The reason for this is that it is now internal competition. For internal competition, the business personnel using our system actually have a great voice, and their satisfaction is likely to be the winner of the final evaluation.

At the same time, we also plan to prepare more experienced data tracking and analysis functions for advertisers who put in our system, so as to maximize the attraction of our products.

2. The stability and reliability requirements of this system are very high. Sometimes it is worthwhile to over design and implement it.

Here we want to explain the meaning of stability and reliability in our scene at that time. Stability is to ensure that the performance is stable, that is, our system response time should try our best to ensure that it responds in a very short time.

Reliability is that our system should try its best to ensure that there are no errors, because errors are likely to cause the loss of users and the failure of our products.

After setting goals and providing product requirements, I entered an extremely difficult development work with the team. At that time, I really paid my heart and soul.

In fact, I was a man who enjoyed life better than worked hard. Although I was busy with my work before, I had a very pleasant time in my spare time. Listen to music, watch movies, sometimes find a restaurant with his wife to enjoy delicious food, and sometimes play a hearty football.

However, since I began to invest in the development of this advertising system, the leisurely days are gone.

I remember when I stumbled off work and came to work. At that time, my biggest wish was to have a bed and lie down and never wake me up.

But even so hard, I still encountered a number of unclear problems. These hard bones across the development road led to my development goals being adjusted again and again.

One of the most troublesome is the performance problem of high concurrency.

At that time, my experience was still shallow. To be honest, the surrounding ecology was not perfect. What can be used to host access is cache and database. At the same time, due to copyright and other problems, I can only choose MySQL database.

In order to solve these performance problems, I also specially printed out the official MySQL manual and studied it every day.

At the beginning, in order to resist the expected ultra-high concurrency, I adopted the popular read-write separation mode at that time.

However, in the actual test, there are always all kinds of dissatisfaction. One of the most troublesome is the performance of various complex queries.

I said that in order to win the internal competition, we try our best to rely on the two goals of high concurrency and multi-function. Therefore, for these two goals, the system actually has many functions that are convenient for business personnel, and the envisaged objectives of this function are:

In the high parallel, it still remains stable and smooth.

Among them, the most typical business is the advertising ranking function that can be updated in real time.

The demand for this advertising ranking is as follows:

  • First of all, our users should be able to see their own advertising ranking in the management background. The ranking is arranged according to indicators such as the amount of consumption and the number of clicks.
  • Secondly, in our backstage, we also made such a ranking for business personnel. The difference is that it is an overall ranking and a total ranking of advertisements put by all our customers.
  • Then, the ranking should be able to change in real time according to the change of consumption amount and click times. Of course, this real-time can be made into quasi real-time, as long as it doesn’t delay too much.

As for itself, there are many indicators used for ranking, so you need to write very complex SQL to query in the database. In addition, if you need real-time changes, you have to keep querying in the database.

In this case, I can’t get satisfactory results anyway. If I cache this ranking, because this ranking needs various statistics and sorting, it also needs various model conversion after querying from the database. If the concurrency comes up, the query will be converted again, and the performance will really drop rapidly.

At that time, I was under great pressure. My mind was always thinking about performance problems. The MySQL manual in my hand was almost rotten and lost pages. Even when I go home to sleep, I close my eyes and always think about how to solve these problems.

The time for the final launch is approaching, but the project in hand is stuck, which is difficult to make progress on these performance problems, but the competitors hear the news that the internal competitors are progressing smoothly to a certain extent from time to time.

I can’t bear all this, and the voice of persuading myself to give up is getting louder and louder.

I once thought I was a very resilient person, but now it seems that I am just an ordinary wage earner.

I want to escape. I want to discuss with the product. Let’s go online like this. I don’t want to take care of it. It’s up to God whether it’s dead or alive. The other party also encounters such problems as me, and it’s even worse than me.

Just when I was ready to pull the product and finally decided to go online, I was strongly unwilling to stop me. I think before I give up, I should know how the competitor is and what plans and ideas the other party has for my reference.

I searched all my company acquaintances to keep asking about my competitors. However, the result was not good, because the other party did better than me. They carried out closed development and were very vigilant.

In the end, I only got one keyword:CQRS。 The other party uses cqrs to solve performance problems!!!

When I was young, I didn’t have a mobile phone at that time. I can always do a good job of reading wholeheartedly. My reading efficiency is very high. But now that I have a mobile phone, when I read again, I always distract myself from looking at the information in the mobile phone from time to time. Sometimes, in order to read the book well, I have to leave my mobile phone at a distance to prevent distraction.

Cqrs is such an idea. This model is not so much an architecture model as an idea.

Cqrs believes that the operations in a system can be divided into two categories: read and write. If a system does not specifically optimize reading and writing separately, the system will be dual-purpose like I read with my mobile phone, so their performance cannot be optimized due to mutual influence.

Therefore, reading and writing should be separated and optimized separately.

In cqrs,The act of writing is called a command, and the act of reading is called a query。 Because they want to separate, cqrs mode is called in Chinese translationCommand query authority responsibility separation mode

After I knew this idea, I didn’t care, because at first glance, this set of things is actually the same as the read-write separation of the database I used, that is, to separate the read-write from the database.

However, my technical intuition tells me that this is not so simple.

In the computer world, a noun will not appear or become popular for no reason. If it is really the same as the read-write separation of the database, it should be directly called the read-write separation of the database. There must be something different.

I was no longer satisfied with Chinese search results. I went directly to Martin flower’s website to see the original version. Then I found such an architecture diagram.

Combined with his original text, I suddenly understood,It’s a model, different from the model!

The original database read-write separation does separate the two behaviors of read-write, but it still has an important thing not done, that is, the separation of responsibilities.

What is the separation of duties? That is, both reading and writing should not engage in the same set of models. The problem of database read-write separation is here. It uses the same model.

The problem caused by using the same model here is that it should not be too difficult to read data and write data.

This violates the core idea of cqrs:Complete freedom of reading and writing

If we use cqrs thinking, assuming that writing does not need to care about reading and reading data does not need to care about writing, can both sides completely release themselves?

For example, since there is no need to consider reading when writing data, I can use JSON format, non-standard format such as XML format, or even write a log directly. Reading data doesn’t need to consider writing at all. I can even make it into an easy to search index format.

In my opinion, cqrs is a panacea to solve the performance problem of jamming me.

Take the problem of advertising ranking as an example. The trouble of advertising ranking is that every time you load the ranking, you need to have a very complex query to read data from the database.

If you can completelyReading of LeaderboardandThe ranking list depends on the update of click and consumption indicatorsSeparate, then my troubled leaderboard performance problem can be solved.

After making great efforts, I followed the original idea of cqrs and developed such a design idea:

Here, data statistics is the click, consumption and other data required for advertising ranking. These data will be put into a separate database, which is only used for writing, not reading.

Then, the function of displaying advertising ranking itself will directly read the model of advertising ranking from the cache and display it without any special conversion. There is no complex query problem.

However, our demand is to let the advertising ranking update automatically according to the click, consumption and other data in quasi real time. What should we do if the write data and read data models are separated?

Many years ago, when I first bought things online, I had a question in my heart: How did the merchant who sold my things know when I placed an order? Do you have to keep staring?

I didn’t know this until I personally developed the e-commerce system. When we place an order, we need to send a notice to the corresponding merchant to tell the merchant which customer purchased which product.

Therefore, the solution of automatic updating of advertising ranking is, which is the same as that of e-commerce placing an order and notifying merchants. When data is written, we can copy the written data and notify the model reading the data.

OK, now the whole logic is complete.

However, I am not in a hurry to apply the cqrs model to practical projects immediately. Because I found that I didn’t know what the disadvantages of cqrs model were.

You know, there are no perfect solutions in the world. They all have both advantages and disadvantages. And cqrs I actually feel that it perfectly solves my problem, which shows that there are still problems in my cognition of this model.

At that time, the agreed online time was getting closer and closer, and there was almost a week left. I really want to close my eyes and carry out the plan.

However, I can’t. I always like to think things through and do it after I know things very clearly.

I decided to take a risk to realize two function points in two days, and then personally experience the gains and losses of introducing cqrs.

Two days later, I finally found the problem:After the introduction of cqrs, the biggest problem is the introduction of excessive complexity

Due to the need to separate reading and writing, our development workload has been virtually doubled. Cqrs is introduced again, which becomes more complex.

Because we found that different functions can make full use of the advantages of cqrs only by using different read or write models.

For example, advertising rankings may use caching middleware to access ready-made rankings. If you search for various suitable advertisements according to keywords, you may have to consider open-source search engine middleware. Each introduction will increase the development cost, server cost, and more complexity.

Finally, our advertising system went online on time.

However, cqrs mode is not widely adopted. I just use cqrs for the most important function points. I decided to put aside the other performance problems for the time being.

This is because I think most of the problems are actually caused by our over design. Even if I failed, I would admit it.

I don’t want to bury huge hidden dangers for the system I personally built, let alone bring unnecessary workload to the team. I don’t want to be involved in this.

After going online, I was so nervous, especially in the first two months of online operation.

I don’t know whether my compromise will cause huge problems, and I don’t know whether my actions are really right.

The competition between the two systems will have a result two months after it is launched.

It is precisely because my opponent widely uses cqrs mode that I get the result so quickly.

From the beginning of his design, he thought of a blockbuster. Seven or eight kinds of middleware were introduced into his system. A large number of functions are divided into read and write parts, which leads to a huge disaster. The excessive complexity makes the whole system difficult to control.

The biggest headache is that due to the introduction of cqrs, they must communicate, read and write two sets of components through message transmission.

However, when the read component receives the message, it finds that the write failed. After seeing the corresponding data, the user finds that the data does not match the previous data after a period of time.

For example, the number of clicks was 1000 at first, but two hours later, it was 999.

Such problems occur every day, and because the system is too complex, the time to check, locate and solve problems has been greatly prolonged. Finally, the customers quit one after another, so the company had to transfer the customers to my platform.

The competition is over and I won, but I really can’t be happy. Because today he failed because of the wrong introduction of new technologies, why won’t I fail because of the misuse of new technologies and ideas tomorrow? Is today’s him not tomorrow’s me?

May programmers all over the world think and be familiar with everything, speak and act carefully!


Hello, I’m four apes.

He is the technical director of a listed company and manages more than 100 technical teams.

I changed from a non computer major graduate to a programmer. I worked hard and grew all the way.

I will write my own growth story into an article and a boring technical article into a story.

Welcome to my official account.After paying attention, you can also obtain dry goods learning materials such as algorithms and high concurrency

I set up a reader exchange group, most of which are programmers. They talk about technology, work and gossip together. Welcome to wechat and join us.