Ok, Nhưng Nó Có Mở Rộng Được Không? Kiến Trúc Co Giãn Của SpacetimeDB
Bài viết phân tích sâu về ba chiều mở rộng quy mô (compute, storage, networking) và lập luận rằng mở rộng ngang không phải lúc nào cũng là giải pháp tối ưu, đặc biệt khi gặp tranh chấp dữ liệu. SpacetimeDB chọn kiến trúc đơn luồng hiệu năng cao cho từng database và cung cấp bộ công cụ sharding, lưu trữ phân tầng để giúp nhà phát triển mở rộng khối lượng công việc OLTP có thể song song hóa một cách hiệu quả.

Ok, Nhưng SpacetimeDB Có Mở Rộng Được Không?
SpacetimeDB, cơ sở dữ liệu thời gian thực nổi tiếng với hiệu năng ấn tượng, thường xuyên nhận được câu hỏi về khả năng mở rộng quy mô. Câu trả lời không đơn giản chỉ là "có" hay "không", mà nằm ở việc hiểu rõ ba chiều mở rộng khác nhau và cách kiến trúc của SpacetimeDB giải quyết từng vấn đề một cách thông minh, thách thức quan điểm truyền thống về mở rộng ngang.
Ba Chiều Của Sự Mở Rộng
Hầu hết mọi người khi nói về khả năng mở rộng đều nghĩ đến mở rộng ngang – thêm nhiều máy tính hơn để xử lý nhiều việc hơn. Tuy nhiên, câu hỏi này thường thiếu chính xác. Một hệ thống có thể mở rộng theo ba chiều khá độc lập:
- Compute (Xử lý): Số lượng giao dịch (transaction) bạn có thể xử lý.
- Storage (Lưu trữ): Lượng dữ liệu bạn có thể lưu trữ.
- Networking (Mạng): Số lượng kết nối và băng thông bạn có thể hỗ trợ.
Để hiểu rõ hơn, hãy so sánh cách các hệ thống cơ sở dữ liệu khác nhau xử lý ba chiều này. Postgres truyền thống là một hệ thống đơn nút, không tự động mở rộng bất kỳ chiều nào. Neon, một biến thể của Postgres, mở rộng storage theo chiều ngang bằng cách đưa dữ liệu lên object storage, nhưng compute và networking vẫn giới hạn ở một primary duy nhất. Trong khi đó, CockroachDB (và Spanner) tuyên bố mở rộng cả ba chiều bằng kiến trúc phân tán đối xứng.
Vậy nếu CockroachDB tuyệt vời như vậy, tại sao vẫn cần các hệ thống khác? Câu trả lời nằm ở chi phí tiềm ẩn của việc mở rộng ngang.
Nghịch Lý Của Việc Mở Rộng Ngang
Điểm mấu chốt là không phải mọi tính toán đều có thể mở rộng theo chiều ngang. Bài toán này quy về khả năng chia nhỏ công việc cho nhiều máy tính thực hiện song song. Với các giao dịch tranh chấp dữ liệu (contending transactions), câu trả lời thường là "không".
Sự thật phũ phàng là thay vì làm được nhiều hơn với nhiều máy tính hơn, mở rộng ngang thường có nghĩa là làm được ít hơn với nhiều máy tính hơn: về mặt khái niệm, những gì một máy tính làm trong 1 mili giây, 10 máy tính có thể mất 100 mili giây.
Hãy tưởng tượng một giao dịch OLTP nhỏ chỉ cần sửa một dòng dữ liệu. Trên Postgres đơn nút, điều này chỉ mất khoảng 3 micro giây (µs). Nhưng trên một cụm CockroachDB, dữ liệu có thể nằm trên các máy khác nhau, buộc giao dịch phải trải qua nhiều vòng kết nối mạng, khiến thời gian xử lý tăng lên cả mili giây (ms). Tồi tệ hơn, các giao dịch khác muốn truy cập cùng dữ liệu phải chờ đợi, giảm đáng kể thông lượng.
Một điểm nóng với critical section 3 µs có thể xử lý khoảng 300.000 giao dịch tranh chấp mỗi giây. Nhưng ở mức 1 ms, con số này tụt xuống chỉ còn 1.000 tps. Thật phản trực giác, nhưng giải pháp đơn luồng lại "mở rộng" hơn gấp 300 lần trong tình huống này! Ngay cả với chỉ 1% giao dịch tranh chấp trên một dòng, mọi cụm mở rộng ngang đều chậm hơn một lõi đơn. Đây chính là định luật Amdahl áp dụng cho việc mở rộng ngang.
Vậy nên, việc mở rộng ngang không hẳn là một thuộc tính mà hệ thống có hay không, mà chủ yếu là một thuộc tính của khối lượng công việc (workload).
Kiến Trúc Của SpacetimeDB: Đơn Luồng Nhưng Không Đơn Điệu
SpacetimeDB chọn một con đường khác. Mỗi database trong SpacetimeDB là một actor đơn luồng (single-threaded actor) được thiết kế để đạt hiệu năng cực cao. Nghe có vẻ "không thể mở rộng", nhưng thực tế đây là sự lựa chọn kiến trúc có chủ đích để tối ưu cho các khối lượng công việc OLTP có tranh chấp – nơi mà các hệ thống phân tán khác thất bại thảm hại.
Kiến trúc này được lấy cảm hứng từ mô hình actor, một mô hình tính toán song song tổng quát, đặc biệt phù hợp cho các hệ thống có hàng chục, hàng trăm hoặc thậm chí hàng nghìn bộ xử lý độc lập giao tiếp qua mạng. Trong SpacetimeDB Cloud, mỗi database đơn luồng này có thể được nhân bản trên nhiều máy (distributed state machine replication) để đảm bảo độ tin cậy mà không làm giảm thông lượng.
Sơ đồ minh họa kiến trúc SpacetimeDB
Để mở rộng quy mô, SpacetimeDB vạch ra lộ trình 6 bước rõ ràng:
| Bước | Tính năng | Trạng thái |
|---|---|---|
| 1 | Nhân bản database với hiệu năng đẳng cấp thế giới | Hiện tại |
| 2 | Trải nghiệm sharding đẳng cấp thế giới (giao tiếp liên database bất đồng bộ - async IDC) | 31/10/2026 |
| 3 | Mở rộng storage theo chiều ngang cho mỗi database (lưu trữ phân tầng) | 31/10/2026 |
| 4 | Mở rộng networking theo chiều ngang (consistent read replicas) | Đã lên kế hoạch |
| 5 | Triển khai giao dịch liên database (sync IDC) | Đã lên kế hoạch |
| 6 | Triển khai phân vùng nội bộ database (intra-database partitioning) | Đã lên kế hoạch |
Bước 1 & 2: Sharding Chủ Động
Ngay từ hôm nay, các nhà phát triển có thể mở rộng khối lượng công việc song song bằng cách chia dữ liệu ra nhiều database khác nhau (sharding). Các database hoạt động như các actor độc lập, thực hiện giao dịch một cách đồng thời mà không cần phối hợp phức tạp. Các khách hàng của SpacetimeDB đã vận hành hàng trăm hoặc thậm chí hàng nghìn database theo cách này.
Sắp tới, giao tiếp liên database bất đồng bộ (Async IDC) trong bản phát hành Spacetime Continuum vào 31/10/2026 sẽ giúp việc này dễ dàng hơn, cho phép một database gọi hàm một cách type-safe trên database khác.
// Async IDC: gửi một message type-safe đến database khác.
// Điều này sẽ dẫn đến đúng một reducer call trên database đích.
ctx.db.receivePlayer.insert({
msgId: 0n,
target: regionDb,
player,
});
Bước 3: Lưu Trữ Phân Tầng
Một giới hạn lớn của việc lưu toàn bộ dữ liệu trong RAM là chi phí. SpacetimeDB xem bộ nhớ RAM như L4 cache, ổ cứng như L5 cache, và object storage như L6 cache. Cách tiếp cận này, gọi là "tiered storage", cho phép lưu trữ một lượng dữ liệu gần như không giới hạn trong một database duy nhất.
Vậy làm thế nào để tránh việc một cache miss 50ms làm tê liệt toàn bộ database đơn luồng? Kỹ thuật anti-caching từ H-Store là câu trả lời: nếu một giao dịch chạm vào dữ liệu không có trong bộ nhớ, nó sẽ bị hủy bỏ, dữ liệu được tải lên một cách bất đồng bộ, và các giao dịch khác tiếp tục xử lý trong lúc chờ. Khi dữ liệu đã sẵn sàng, giao dịch sẽ được chạy lại. Việc hủy bỏ gần như "miễn phí" vì chưa có gì được cam kết.
SpacetimeDB cực kỳ phù hợp với các kỹ thuật này vì các reducer là deterministic (xác định). Chúng không thể thực hiện I/O, đọc đồng hồ hay tạo số ngẫu nhiên. Điều này có nghĩa là việc hủy bỏ không có tác dụng phụ và việc chạy lại trên cùng một trạng thái sẽ chạm vào cùng một dữ liệu. Đây là chiến lược mà đội ngũ TigerBeetle gọi là "mở rộng theo đường chéo".
Bước 4: Mở Rộng Networking với Read Replicas
Cũng giống như compute, việc mở rộng networking theo chiều ngang không phải lúc nào cũng khả thi, nhất là khi nhiều writer muốn ghi vào cùng một dữ liệu. Nhưng đối với việc đọc, SpacetimeDB Cloud có kiến trúc đối xứng: bạn có thể kết nối đến bất kỳ nút nào, và nút đó sẽ chuyển tiếp yêu cầu đến đúng nơi cần xử lý. Kiến trúc này cho phép "fan-in" các kết nối từ nhiều client.
Trong tương lai, consistent read replicas sẽ cho phép "fan-out" từ leader. Việc xử lý các subscription và câu lệnh đọc có thể được chuyển đến các bản sao nhất quán, giúp mở rộng số lượng kết nối đọc một cách hiệu quả. Các bản sao này áp dụng transaction log theo cùng một thứ tự, do đó subscription sẽ thấy một chuỗi cập nhật giống hệt nhưng bị trễ. Điều này đảm bảo tính nhất quán (linearizability) mà không làm tăng gánh nặng cho leader.
Vậy, SpacetimeDB Có Mở Rộng Được Không?
Câu trả lời là Có. Ngay hôm nay, bạn có thể mở rộng khối lượng công việc song song bằng cách chia chúng ra nhiều database. Kiến trúc này gần như là lựa chọn tốt nhất nếu khối lượng công việc của bạn có bất kỳ sự tranh chấp nào, hoặc nếu bạn không muốn trả chi phí cho một cụm lớn chỉ để có hiệu năng của một lõi đơn.
Theo thời gian, với lưu trữ phân tầng, giao tiếp liên database, giao dịch phân tán và phân vùng nội bộ, kiến trúc này sẽ ngày càng trở nên minh bạch hơn với nhà phát triển.
Mục tiêu không phải là làm cho sự phối hợp trở nên miễn phí. Mà là đảm bảo bạn chỉ phải trả chi phí đó khi khối lượng công việc của bạn thực sự yêu cầu.
Bài viết gốc của Tyler Cloutier, đồng sáng lập Clockwork Labs.


