Skip to main content

Cloud-Native Storage (Phần 3): CQRS – Tách biệt đọc và ghi để mở rộng hệ thống quy mô lớn

Trong nhiều hệ thống hiện đại, số lượng thao tác đọc thường lớn hơn rất nhiều so với thao tác ghi. Khi cả hai cùng chia sẻ một cơ sở dữ liệu, hiệu năng nhanh chóng trở thành điểm nghẽn và việc mở rộng hệ thống trở nên khó khăn.

Đó là lý do kiến trúc Command Query Responsibility Segregation (CQRS) ra đời. Thay vì sử dụng chung một mô hình dữ liệu, CQRS tách riêng luồng ghi và luồng đọc để mỗi bên được tối ưu cho nhiệm vụ của mình. Đây là một trong những mẫu kiến trúc quan trọng trong Cloud-Native Storage dành cho các hệ thống có quy mô lớn và yêu cầu hiệu năng cao.

7. Command Query Responsibility Segregation (CQRS)

Command Query Responsibility Segregation (CQRS) là một giải pháp cấp cao để giải quyết sự xung đột giữa việc ghi và đọc dữ liệu trong các hệ thống quy mô lớn.

Bản chất: "Chia để trị" giữa Đọc và Ghi

Thông thường, một ứng dụng sẽ dùng chung một cơ sở dữ liệu (CSDL) để vừa tạo mới (Create), vừa đọc (Read), cập nhật (Update) và xóa (Delete) dữ liệu. Tuy nhiên, triết lý cốt lõi của CQRS là không dùng một túi dữ liệu duy nhất mà chia thành hai phần riêng biệt: một bên chuyên để cập nhật dữ liệu (Command) và một bên chuyên để truy vấn dữ liệu (Query).

Hệ thống sẽ giữ hai phần này đồng bộ với nhau: hễ có thay đổi bên "Ghi", nó sẽ tự động cập nhật sang bên "Đọc".

Tại sao phải làm phức tạp như vậy?

Trong thực tế, việc dùng chung một CSDL gây ra ba vấn đề lớn:

  • Xung đột hiệu suất: Khi có quá nhiều người cùng cập nhật dữ liệu, hệ thống phải "khóa" các bản ghi lại để đảm bảo tính chính xác, khiến những người muốn đọc dữ liệu phải xếp hàng chờ đợi.
  • Tối ưu hóa nửa vời: Rất khó để thiết kế một CSDL vừa nhanh khi ghi, vừa nhanh khi đọc. Thường thì việc tối ưu cho bên này sẽ làm hại bên kia.
  • Góc nhìn khác nhau: Người mua hàng muốn nhìn dữ liệu theo kiểu này, nhưng nhân viên kho lại muốn nhìn dữ liệu theo kiểu khác. Một cấu trúc dữ liệu duy nhất khó lòng phục vụ tốt cho tất cả.

Cách vận hành của bộ máy CQRS

CQRS

1. Nhánh Ghi (Write Solution): "Người thực thi mệnh lệnh"

Phía bên trái tập trung vào việc thay đổi trạng thái của hệ thống:

  • Updating Client & Modify API: Người dùng gửi yêu cầu thay đổi (tạo mới, cập nhật, xóa) thông qua một giao diện lập trình (API) chuyên dụng.
  • Command Facade & Command Bus (Tùy chọn): Các yêu cầu được đóng gói thành các Lệnh (Commands). Nếu có quá nhiều yêu cầu cùng lúc, một "Command Bus" (Trục lệnh) sẽ đóng vai trò như một hàng chờ để xếp hàng các lệnh này, giúp hệ thống không bị quá tải.
  • Write Model (Domain Model): Đây là "trái tim" của nhánh ghi, nơi chứa các quy tắc nghiệp vụ phức tạp. Nó xử lý các lệnh một cách tuần tự để đảm bảo dữ liệu luôn chính xác và hợp lệ.
  • Database of Record: Đây là nơi lưu trữ "sự thật" duy nhất và mới nhất của hệ thống. Nhánh Ghi sẽ cập nhật trực tiếp vào đây.
  • Change Log (Tùy chọn): Một nhật ký lưu lại lịch sử mọi thay đổi để có thể phục hồi hoặc kiểm tra khi cần.    

2. Trục kết nối: Event Backbone (Trục sự kiện)

Nằm ở giữa sơ đồ, Event Backbone đóng vai trò là "người đưa tin". Mỗi khi Nhánh Ghi cập nhật xong dữ liệu vào CSDL, nó sẽ phát ra một Sự kiện (Update Event) thông báo rằng: "Này, dữ liệu X đã thay đổi rồi!".

3. Nhánh Đọc (Read Solution): "Người phục vụ thông tin"

Phía bên phải sơ đồ tập trung vào việc hiển thị dữ liệu cho người dùng một cách nhanh nhất:

  • Event Processor: Thành phần này luôn lắng nghe các sự kiện từ Trục sự kiện. Khi thấy có thông báo thay đổi, nó sẽ cập nhật ngay lập tức vào Query Database để bên Đọc luôn có dữ liệu mới.
  • Query Database (CSDL Truy vấn): Đây là một bản sao (replica) của "Database of Record" bên ghi nhưng được tối ưu hóa hoàn toàn cho việc tìm kiếm và báo cáo.
  • Read Model: Thực hiện các câu lệnh truy vấn vào CSDL Truy vấn và đóng gói kết quả thành các Data Transfer Objects (DTOs) — là những cấu trúc dữ liệu gọn nhẹ, chỉ chứa đúng những gì người dùng cần xem.
  • Retrieve API & Querying Client: Người dùng chỉ việc đặt câu hỏi (truy vấn) và nhận lại thông tin một cách nhanh chóng mà không làm ảnh hưởng đến hiệu suất của bên Ghi.       

4. Tại sao cấu trúc này lại mạnh mẽ?

Sơ đồ này giải quyết các bài toán khó mà CSDL truyền thống thường "đầu hàng":

  • Tối ưu hóa riêng biệt: Bạn có thể dùng CSDL Key-Value ở bên Ghi để đạt tốc độ cực nhanh, nhưng dùng CSDL Columnar (dạng cột) ở bên Đọc để tạo báo cáo khổng lồ chỉ trong vài giây.
  • Không còn xung đột: Người đang sửa dữ liệu không làm chậm người đang xem dữ liệu và ngược lại, vì họ thao tác trên hai CSDL khác nhau.
  • Khả năng mở rộng: Bạn có thể chạy 20 máy chủ cho bên Đọc (vì người dùng xem nhiều) nhưng chỉ cần 3 máy chủ cho bên Ghi.       

5. Sự đánh đổi: Nhất quán cuối cùng (Eventual Consistency)

Sơ đồ cũng ngầm chỉ ra một thách thức: Vì dữ liệu phải đi qua Trục sự kiện để sang bên Đọc, nên sẽ có một khoảng trễ cực ngắn (vài mili giây). Trong khoảnh khắc đó, người đọc có thể thấy dữ liệu hơi "cũ" một chút so với người vừa ghi xong. Bạn chấp nhận điều này để đổi lấy hiệu suất và quy mô siêu lớn của hệ thống đám mây.

CQRS cực kỳ hữu ích khi bạn muốn hiện đại hóa một hệ thống cũ (Monolith) mà không thể đập đi xây lại toàn bộ. Bạn có thể giữ hệ thống cũ làm nhánh Ghi và xây dựng một nhánh Đọc mới linh hoạt hơn trên đám mây.

CQRS là một giải pháp kiến trúc "hạng nặng" dành cho những bài toán khó, nơi mà sự tách biệt giữa hành động thay đổi thế giới (Ghi) và hành động quan sát thế giới (Đọc) mang lại hiệu suất và khả năng mở rộng không giới hạn.

Kết luận

CQRS không phải là giải pháp dành cho mọi ứng dụng, nhưng nó trở nên cực kỳ giá trị khi hệ thống cần xử lý lượng truy cập lớn, tối ưu hiệu năng và mở rộng độc lập giữa đọc và ghi. CQRS hoàn thiện bức tranh về Cloud-Native Storage, nơi dữ liệu không chỉ được lưu trữ an toàn mà còn được tổ chức để phục vụ hiệu quả cho các hệ thống phân tán quy mô lớn.

Comments

Popular posts from this blog

Cloud Native là gì? Tư duy thiết kế hệ thống hiện đại cho thời đại đám mây

Cloud Native đang trở thành nền tảng của hầu hết các hệ thống hiện đại từ Netflix, Amazon đến Google. Nhưng Cloud Native thực sự là gì? Liệu việc đưa ứng dụng lên AWS hay Google Cloud đã đủ để gọi là Cloud Native chưa? Trong bài viết này, chúng ta sẽ tìm hiểu nguồn gốc của khái niệm Cloud Native, bài học từ sự cố AWS năm 2015, và những đặc tính quan trọng giúp các hệ thống hiện đại đạt được khả năng mở rộng, chống chịu và triển khai liên tục. 1. Bài học từ sự cố AWS: Lỗi là “Luật”, không phải “Ngoại lệ” Vào năm 2015, Amazon Web Services (AWS) gặp sự cố sập mạng chấn động. Trong khi các “ông lớn” như Airbnb hay Nest đều bị tê liệt, thì Netflix chỉ bị ảnh hưởng rất nhỏ và phục hồi gần như ngay lập tức. AWS phân vùng các dịch vụ mà nó cung cấp thành các vùng (region) và vùng khả dụng (Availability Zone - AZ). Các vùng ánh xạ đến các khu vực địa lý (như Virginia, California, Oregon) và AZ cung cấp thêm dự phòng và cô lập trong một vùng duy nhất. Hình bên dưới hoàn toàn là giả định (nhưng v...

Kiến trúc cho xử lý dữ liệu luồng (Streaming Architecture) - Phần 3: Continuous Intelligence và AI thời gian thực

Khi hệ thống đã có khả năng thu thập dữ liệu liên tục và phân tích sự kiện theo thời gian thực, câu hỏi tiếp theo là: liệu máy tính có thể tự đưa ra quyết định thay con người hay không? Kiếntrúc cho xử lý dữ liệu luồng (Streaming Architecture) - Phần 1: Giá trị củaStreaming và Kiến trúc Streaming Ingest Kiếntrúc cho xử lý dữ liệu luồng (Streaming Architecture) - Phần 2: Real-timeDashboards và Stream Analytics Đó chính là mục tiêu của Continuous Intelligence – giai đoạn cao nhất trong kiến trúc xử lý dữ liệu luồng. Thay vì chỉ hiển thị cảnh báo trên dashboard, hệ thống có thể liên tục huấn luyện mô hình AI, thực hiện suy luận (Inference) ngay khi dữ liệu phát sinh và tự động kích hoạt các hành động phù hợp. Trong bài viết cuối cùng của series Kiến trúc cho xử lý dữ liệu luồng , chúng ta sẽ cùng khám phá cách xây dựng một hệ thống dữ liệu thông minh có khả năng học hỏi, thích nghi và phản ứng gần như theo thời gian thực. 5. Continuous Intelligence (Trí tuệ liên tục) Đây là cấp...

Reinforcement Learning (Học tăng cường) là gì? Hiểu bản chất qua giải thích về cách AI tự học

Nếu học có giám sát giúp AI học từ những đáp án đã biết trước, còn học không giám sát giúp AI tự khám phá cấu trúc của dữ liệu, thì học tăng cường (Reinforcement Learning - RL) lại đi theo một hướng hoàn toàn khác: AI học bằng chính trải nghiệm của mình. Deep Reinforcement Learning là gì? Vì sao AI cần kết hợp Học sâu với Học tăng cường Reinforcement Learning (Học tăng cường) hoạt động như thế nào? Dynamic Programming, Monte Carlo và các ứng dụng thực tế Thay vì được hướng dẫn từng bước, tác nhân (agent) liên tục tương tác với môi trường, thử nhiều hành động khác nhau và nhận phần thưởng hoặc hình phạt. Sau hàng nghìn, thậm chí hàng triệu lần thử nghiệm, AI dần học được chiến lược tối ưu để đạt mục tiêu. Trong bài viết này, chúng ta sẽ cùng tìm hiểu bản chất của học tăng cường, các thành phần quan trọng như Agent, Environment, Reward, Action và Observation, đồng thời minh họa bằng ví dụ trực quan để thấy AI thực sự "học" như thế nào. 1. Học có giám sát (Supervised learni...