Sổ tay Kiến trúc Phần mềm
10 Phần II · Phong cách Chương 15

Space-Based Architecture

Space-Based Architecture (SBA)

Sinh ra để giải một bài toán duy nhất: mở rộng cực hạn với tải biến động khó lường. Bí quyết táo bạo — gỡ cơ sở dữ liệu ra khỏi đường giao dịch, giữ dữ liệu trong bộ nhớ sao chép giữa các đơn vị xử lý.

01 Vấn đề & ý tưởng

Trong web truyền thống, dễ scale web/app server, nhưng CSDL là nút cổ chai cuối cùng: tải cao tới mức tạo "hình tam giác" thắt lại ở DB. Vá bằng cache hay scale DB đều khó & đắt.

Giải bài toán mở rộng cực hạn ở tầng kiến trúc thường tốt hơn là cố scale DB hay nhồi cache vào một kiến trúc vốn không scale được.

Richards & Ford

Tên gọi đến từ tuple space — nhiều bộ xử lý song song giao tiếp qua bộ nhớ dùng chung. Ý tưởng cốt lõi: bỏ DB khỏi đường giao dịch đồng bộ, giữ dữ liệu in-memory replicated trên mọi processing unit. Không còn nút cổ chai DB → mở rộng "gần như vô hạn".

Ba điểm mạnh dẫn dắt: Elasticity, Scalability, Performance — cả ba đều 5★. Đổi lại là sự phức tạp (xử lý nhất quán cuối cùng & chống mất dữ liệu).

02 Bốn nhóm thành phần

flowchart TB
  REQ["Request (tải biến động)"]:::ext --> MG["Messaging Grid
(định tuyến + session)"]:::mw MG --> PU1["Processing Unit + cache"]:::pu MG --> PU2["Processing Unit + cache"]:::pu MG --> PU3["Processing Unit + cache"]:::pu PU1 <-->|"Data Grid replicate <100ms"| PU2 PU2 <-->|"replicate"| PU3 DM["Deployment Manager
(bật/tắt PU theo tải)"]:::mw -.giám sát.-> PU1 DM -.-> PU2 DM -.-> PU3 classDef ext fill:#f3e6c8,stroke:#9a6712,color:#1c1a14; classDef mw fill:#14233b,stroke:#14233b,color:#f3ede0; classDef pu fill:#e7ddf2,stroke:#6a4ca8,color:#1c1a14;
Mọi PU giữ đúng cùng một dữ liệu in-memory; messaging grid gửi request tới PU rảnh bất kỳ. Data grid đồng bộ giữa các PU (thực tế bất đồng bộ, thường <100ms).

Processing Unit

đơn vị xử lý

Chứa logic ứng dụng + in-memory data grid (Hazelcast, Apache Ignite, Coherence). Đọc/ghi cache, không đụng DB trực tiếp.

Messaging Grid

quản lý request & session

Chọn PU còn rảnh để chuyển request (round-robin → next-available). Thường là load balancer (HAProxy, Nginx).

Data Grid

quan trọng nhất

Sao chép dữ liệu giữa các PU cùng tên cache để mọi PU giống hệt nhau. Đây là trái tim của SBA.

Deployment Manager

bật/tắt PU động

Theo dõi tải & thời gian phản hồi để khởi chạy/tắt PU — cốt lõi của tính đàn hồi (elasticity).

Processing Grid (tùy chọn): điều phối request khi một giao dịch cần phối hợp nhiều loại PU khác nhau.

03 Đồng bộ về DB — bất đồng bộ

Vì PU không đọc/ghi DB trực tiếp, dữ liệu chảy về kho thật qua ba thành phần — luôn bất đồng bộ, cho nhất quán cuối cùng giữa cache & DB:

Data Pump

PU cập nhật cache → trở thành "chủ" thay đổi → đẩy update qua messaging (hàng đợi bền vững, FIFO) tới data writer. Decoupling: writer chết thì PU vẫn chạy.

Data Writer

Nhận từ data pump & ghi thật vào DB. Thường theo domain (Customer) hoặc riêng từng loại PU (Wallet).

Data Reader

Chỉ đọc DB khi cần khôi phục: mọi PU của một cache sập, redeploy toàn bộ, hoặc lấy dữ liệu lưu trữ. PU đầu tiên giành lock thành "chủ cache tạm" rồi nạp lại qua reverse data pump.

Java · replicated map (Hazelcast)
HazelcastInstance hz = Hazelcast.newHazelcastInstance();
Map<String, CustomerProfile> cache = hz.getReplicatedMap("CustomerProfile");
// Mọi PU có cùng đoạn này → đổi ở một PU, tự replicate sang tất cả PU khác

04 Xung đột dữ liệu & loại cache

Data collision: ở chế độ active/active, hai PU cùng sửa một mẩu dữ liệu trước khi replicate kịp → ghi đè sai (A đặt kho 490, B đặt 495, rồi B bị replicate đè về 490). Tần suất phụ thuộc: số PU (N), tỉ lệ cập nhật (UR), kích thước cache (S) và độ trễ sao chép (RL).

RL ảnh hưởng cực mạnh: với 72.000 update/giờ, RL = 100ms → ~14 va chạm/giờ (0,02%); giảm RL còn 1ms → chỉ ~0,1 va chạm/giờ. Đó là lý do phải đo RL thực tế ở production.

Replicated vs Distributed caching

Tiêu chíReplicated (mặc định)Distributed
Vị trí dữ liệuIn-memory trong từng PUServer cache trung tâm riêng
Hiệu năngCực nhanh (cục bộ)Thấp hơn (truy cập từ xa)
Chịu lỗiCao — không điểm sập đơnYếu — sập cache server là liệt
Nhất quánThấp hơn (có độ trễ replicate)Cao — dữ liệu một chỗ
Dung lượngGiới hạn RAM máy ảo (~<100MB)Lớn (>500MB)

Cache nhỏ & ít cập nhật → chọn theo nhất quán (distributed) vs hiệu năng/chịu lỗi (replicated). Dữ liệu cần chính xác cao (tồn kho) → distributed; dữ liệu ít đổi (mã/tên tham chiếu) → replicated. Có thể lai bằng near-cache.

05 Rating & hệ RAG

SBA tối đa hoá đàn hồi, mở rộng, hiệu năng (cả ba 5★) — đổi lại cực phức tạp & gần như không test nổi ở quy mô thật.

Tính đàn hồi Elasticity
Hiệu suất Performance
Khả năng mở rộng Scalability
Khả năng triển khai Deployability
Khả năng tiến hóa Evolutionary
Khả năng chịu lỗi Fault tolerance
Độ tin cậy Reliability
Chi phí tổng thể Overall cost
Tính mô-đun Modularity
Sự linh hoạt Agility
Tính đơn giản Simplicity
Khả năng kiểm thử Testability

Hợp với: bán vé hoà nhạc, đấu giá trực tuyến — tải vọt từ vài trăm lên hàng chục nghìn người trong vài phút, không đoán trước được. Tránh khi: ngân sách hạn chế (phí license cache + tài nguyên cloud) hoặc không kham nổi việc test đàn hồi quy mô lớn.

Khi nào RAG cần SBA?

RAG  Một tài liệu/sự kiện "viral" khiến cả công ty hỏi cùng lúc → vector DB thành nút cổ chai. Giữ chunk & embedding "nóng" trong data grid replicated, Deployment Manager bung thêm query node theo tải, data pump async-ghi ingest mới về vector DB.

flowchart TB
  Q["Truy vấn dồn dập"]:::ext --> MG["Messaging Grid"]:::mw
  MG --> R1["RAG node + cache embedding nóng"]:::pu
  MG --> R2["RAG node + cache embedding nóng"]:::pu
  R1 <-->|replicate| R2
  R1 -->|"data pump (async)"| W["Data Writer"]:::mw --> VDB[("Vector DB (kho thật)")]:::db
  classDef ext fill:#f3e6c8,stroke:#9a6712,color:#1c1a14;
  classDef mw fill:#14233b,stroke:#14233b,color:#f3ede0;
  classDef pu fill:#e7ddf2,stroke:#6a4ca8,color:#1c1a14;
  classDef db fill:#e2edf3,stroke:#2f6d93,color:#1c1a14;
            
Truy hồi là đọc nhiều → ít data collision → replicated cache hợp. Vector DB rời khỏi đường truy vấn nóng, chỉ là "system of record" được ghi bất đồng bộ.

RAG  Nhưng nhớ "ít tệ nhất": với RAG nội bộ tải vừa phải, SBA là dùng dao mổ trâu — Service-Based (topic 08) thường đủ & rẻ hơn nhiều. Chỉ rút SBA ra khi tải thực sự cực hạn & biến động.

06 Ghi nhớ nhanh

Gỡ DB khỏi đường giao dịch — dữ liệu in-memory replicated giữa các PU; DB chỉ là kho ghi bất đồng bộ. Hết nút cổ chai.

5★ cho elasticity · scalability · performance — ba động lực chính; đổi lại 1★ simplicity & testability.

4 thành phần — Processing Unit (+ data grid) · Messaging Grid · Data Grid · Deployment Manager (đàn hồi).

Data pump → writer → reader — đồng bộ về DB bất đồng bộ; nhất quán cuối cùng; cẩn thận mất dữ liệu khi sập.

Chỉ rút ra khi tải cực hạn & biến động — bán vé, đấu giá; phức tạp & đắt, đừng dùng cho tải vừa phải.

NguồnChương 15 (Space-Based Architecture Style), Fundamentals of Software Architecture — Mark Richards & Neal Ford, O'Reilly 2020.