CQRS pattern là gì? Ví dụ dễ hiểu về CQRS Pattern

19939

Quay lại với chuỗi bài về pattern và các pattern trong thiết kế hệ thống, bài viết hôm nay xin phép được trình bày một cách rất chi là cẩn thận, dễ hiểu cho anh em về CQRS pattern.

À trước khi bắt đầu thì thông tin thêm cho anh em là pattern này nằm trong danh sách các pattern thường apply vào thiết kế hệ thống.

Dành cho anh em nào chưa biết pattern.

In software engineering, a design pattern is a general repeatable solution to a commonly occurring problem in software design. A design pattern isn’t a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations.

Trong phần mềm, design pattern là một giải pháp chung để giải quyết các vấn đề lặp đi lặp lại trong thiết kế phần mềm. Design pattern không phải là một khuôn mẫu hoàn chỉnh có thể quăng ra thành code luôn. Nó là khuôn mẫu xử lý một vấn đề được sử dụng trong nhiều hoàn cảnh khác nhau.

CQRS pattern

Rồi, tản mản về Design Pattern vậy là đủ, giờ quay qua nhân vật chính (CQRS pattern). Bắt đầu ngay thôi nào!.

1. CQRS pattern là gì?

Vẫn luôn bắt đầu với định nghĩa theo phong cách viết bài của tui. Bóc tách từng chữ từng chữ một.

Đầu tiên thì CQRS là viết tắt của Command and Query Responsibility Segregation. Bóc tách từng chữ ra thì Segregation là phân tách, Responsibility là trách nhiệm. Vậy dịch sơ sơ cái CQRS có nghĩa là phân tách trách nhiệm giữa Command và Query.

Command and Query Responsibility Segregation, a pattern that separates read and update operations for a data store. Implementing CQRS in your application can maximize its performance, scalability, and security. The flexibility created by migrating to CQRS allows a system to better evolve over time and prevents update commands from causing merge conflicts at the domain level

CQRS là pattern chia việc đọc và cập nhật dữ liệu thành 2 phần khác nhau. Ứng dụng CQRS vào ứng dụng có thể giúp nâng cao hiệu năng, khả năng mở rộng và tính bảo mật. Tính linh hoạt khi chuyển qua CQRS cho phép hệ thống phát triển tốt hơn theo thời gian và ngăn các lệnh cập nhật gây xung đột trên cùng một domain.

Vẫn hơi khó hiểu, thôi thì tạm bỏ qua phần định nghĩa ta đi tới từng phần trong đó (Command và Query).

  SAGA Pattern trong Microservices
  Hướng dẫn Java Design Pattern – Object Pool
  

2. Command và Query

CQRS pattern hướng mục tiêu chia tách Command và Query ra thành 2 phần khác biệt. Anh em lưu ý là commands sẽ bao gồm các HTTP method: POST, PUT, DELETE và PATCH.

Còn phần query theo đúng nghĩa tên gọi của gói, chỉ là GET method, lấy data từ DB.

CQRS pattern

Như hình vẽ trên đây thì findProductById sẽ lấy product theo ID. Còn createProduct sẽ gọi method POST, tạo record mới về product. Cả hai phần này đều nằm trong microservices nhưng độc lập với nhau ha.

Sau khi đã hiểu sơ Command là gì, Query là gì?. Giờ là lúc quay ngược trở lại với câu hỏi tại sao lại cần pattern này?. Anh em có hiểu được mục đích sinh ra pattern mới nhớ được lâu, mới trả lời được mục đích của pattern là gì ha.

3. Tại sao lại cần CQRS pattern?

Chính vì CQRS pattern tách GET và các Http method còn lai ra thành hai phần. Mà GET sử dụng để truy vấn data, còn các method khác là để thao tác với dữ liệu. Nên nguyên nhân đầu tiên và dễ hiểu nhất là:

Do nhu cầu giữa việc truy vấn dữ liệu và thao tác với dữ liệu khác nhau. Một ứng dụng có thể thực hiện cả triệu câu query GET hằng ngày nhưng chỉ thao tác insert vài câu.

Một số nguyên nhân khác:

  • Các tiếp cận cả Command và Queries trên cùng một services có thể gây ảnh hưởng tới performance.
  • Sự khác biệt về quyền được thực hiện Commands và Queries khác nhau đôi khi cũng làm services trở nên phức tạp.
  • Dữ liệu có thể bị xung đột khi thực hiện song song cả truy vấn và thao tác.

Tuyển dụng lập trình viên Frontend lương cao tại đây!

CQRS pattern

4. Hiện thực CQRS pattern

Như đã nói ở trên CQRS pattern tách việc đọc và ghi thành 2 models khác nhau. Ta có thể tối ưu cho từng models

  • Phần commands phải dựa trên nhiệm vụ mà nó thực hiện.
  • Trường hợp có nhiều commands, các commands sẽ đem vào hàng đợi để thực hiện bất đồng bộ.
  • Phần Queries chỉ thực hiện truy vấn dữ liệu, không bao giờ thao tác trên dữ liệu. Dữ liệu trả về theo kiểu DTO không giới hạn. Tuỳ thuộc dữ liệu muốn lấy.

Đạt được 3 điểm này là đã hiện thực được CQRS Pattern.

CQRS pattern

5. Ưu nhược điểm

Phù, cuối cùng cũng nói xong về định nghĩa và giải thích. Mong rằng tới đây anh em đã hiểu rõ mục đích của pattern này.

Giờ tới phần ưu nhược điểm, phần này giúp anh em hiểu rõ hơn ưu nhược điểm để cân nhắc lúc nào thì nên apply pattern này.

5.1 Ưu điểm

CQRS pattern có một số ưu điểm có thể nhìn được rõ:

  • Independent scaling (khả năng mở rộng độc lập). Thay vì scale cho cả đọc và ghi thì giờ phần nào nhiều anh em có thể scale phần đó. Nếu truy vấn nhiều có thể maintain, tối ưu phần queries services.
  • Optimized data schemas (các schema khác nhau). Đã chia nhỏ ra hai phần độc lập và đọc và ghi dữ liệu thì có thể tạo các schema khác nhau cho đọc và ghi.
  • Separation of concerns (tách rời các mối quan tâm). Việc tách riêng 2 phần cũng giúp hệ thống dễ bảo trì, linh hoạt hơn trong phát triển và maintain. Phần logic phức tạp có thể đem qua commands, phần queries thì đơn giản hơn, tuy nhiên cần tối ưu tốc độ.

Nói chung tất cả các benefit của CQRS đều nằm ở việc phân tách rõ ràng giữa Commands và Queries.

5.2 Nhược điểm

Toàn ưu điểm nhưng pattern nào cũng tồn tại nhược điểm của riêng nó. Đối với CQRS tồn tại một số nhược điểm:

  • Complexity (phức tạp). Cái này rõ ràng là phân tách sẽ phức tạp hơn nhiều so với cách làm truyền thống. Nếu microservices của anh em còn có Event Sourcing pattern thì lại càng phức tạp. Cái này tui sẽ nói ở bài Event Sourcing ha.
  • Eventual consistency (nhất quán của sự kiện). Khi đã phân tách commands và queries. Sự nhất quán của dữ liệu có thể bị ảnh hưởng. Phần dữ liệu đã ghi vào rồi nhưng queries lấy ra lại chưa có. Cái này là vấn đề lớn

5.3 Lúc nào không nên apply

Pattern này được khuyến cáo không nên apply nếu:

  • Mô hình business đơn giản, không có quá nhiều truy vấn hay thao tác tới dữ liệu.
  • Ứng dụng CRUD đơn giản, hoặc ứng dụng chỉ yêu cầu truy vấn dữ liệu

Viết ra đây không lỡ anh em cứ cắm đầu apply lại mệt, thực chất tách ra cũng không phải dễ mà triển khai.

6. Tham khảo

Bài sau sẽ là Event Sourcing Pattern nha anh em. Ráng biết nhiều để phục vụ được các ý tưởng sáng tạo nha.

Cảm ơn anh em đã đọc bài – Thank you for your time – Happy coding!

Tác giả: Kiên Nguyễn

Xem thêm: 

Xem thêm Việc làm IT hấp dẫn trên TopDev