Sản phẩm
Lakebase Postgres: Kiến trúc lưu trữ đối tượng và WAL cho kỷ nguyên AI Agent
(giờ Việt Nam)
Tóm tắt AI
Databricks giới thiệu Lakebase Postgres, kết hợp lưu trữ đối tượng với WAL nhằm xóa bỏ nút thắt hiệu năng khi AI Agent tương tác với cơ sở dữ liệu OLTP truyền thống.
Bản dịch AI

Các tác nhân (agents) tương tác với cơ sở dữ liệu OLTP truyền thống thường tạo ra các điểm nghẽn tại tầng lưu trữ. Việc triển khai mới, sao chép, khôi phục và tạo bản sao (replica) đều đồng nghĩa với việc di chuyển khối lượng dữ liệu lớn, vốn rất tốn thời gian và chi phí.
Điều ngược lại hoàn toàn đúng với object storage. Ví dụ, Amazon S3 có chi phí thấp, hiệu năng cao và gần như không cần vận hành. Nó tạo ra một tầng lưu trữ có khả năng mở rộng và tiết kiệm chi phí cho bộ nhớ của tác nhân.
Điều này dẫn chúng ta đến câu hỏi: Liệu object storage có thể nằm bên dưới một cơ sở dữ liệu giao dịch và giúp các tác nhân làm việc dễ dàng hơn không?
Câu hỏi này chính là khởi nguồn của Lakebase Postgres. Câu trả lời không chỉ phụ thuộc vào tốc độ của object store, mà còn phụ thuộc vào việc bạn đặt "nguồn sự thật" (source of truth) ở đâu.
Hai mô hình OLTP
Mô hình tư duy thông thường cho OLTP là lấy dữ liệu làm trung tâm (data-centric). Dữ liệu được tổ chức thành các bảng với hàng và cột, mỗi hàng đại diện cho một thực thể. Lưu trữ là nơi chứa trạng thái hiện tại, và công việc của cơ sở dữ liệu là lưu trữ và truy xuất nó.
Nhưng có một mô hình thứ hai: lấy giao dịch làm trung tâm (transaction-centric). Ở đây, cơ sở dữ liệu là một nhật ký các giao dịch. Mỗi mục nhập là một thao tác, và lưu trữ là một dòng thời gian của các thao tác đó thay vì một ảnh chụp nhanh của hiện tại. Trạng thái hiện tại chỉ là một thứ bạn có thể suy ra từ dòng thời gian đó.
Trong nhiều năm, mô hình lấy dữ liệu làm trung tâm là mô hình duy nhất quan trọng trong thực tế, vì những gì đội ngũ vận hành yêu cầu ở cơ sở dữ liệu là đọc và ghi dựa trên hiện tại. Trong vài năm qua, điều đó đã thay đổi đáng kể. Các thao tác mà khối lượng công việc của tác nhân yêu cầu hầu hết đều là các thao tác trên lịch sử giao dịch:
Đây đều là các truy vấn về dòng thời gian. Một cơ sở dữ liệu chỉ lưu trữ hiện tại sẽ tạo ra các bản sao và bản dự phòng, vốn chậm và đắt đỏ.
Tuy nhiên, Postgres đã chứa sẵn dòng thời gian này: nó được gọi là write-ahead log (WAL).
Việc ghi trong WAL
WAL của Postgres ghi lại mọi sửa đổi trước khi nó đến được các tệp dữ liệu. Ban đầu, nó tồn tại để Postgres có thể phục hồi: nếu máy chủ bị sập giữa quá trình ghi nhật ký và ghi tệp dữ liệu, việc phát lại WAL (WAL replay) sẽ lấp đầy khoảng trống đó.
Nhưng nội dung của WAL còn thú vị hơn nhiều so với việc chỉ phục hồi. Hãy lấy một bảng và một lệnh insert làm ví dụ:
Trước khi thay đổi đó đến được bảng users trên đĩa, Postgres sẽ thêm nó vào WAL. Nhật ký này ở dạng nhị phân, nhưng pg_waldump sẽ hiển thị nó. Các bản ghi cho lệnh insert này trông đại khái như sau:
Đây là bốn bản ghi và một giao dịch. Lưu ý cách mỗi bản ghi có một log sequence number (LSN), một định danh tăng dần đơn điệu.
Các dòng heap và btree cũng nêu tên chính xác trang 8 KB đã thay đổi. Nhật ký không nói "một hàng đã được thêm vào". Nó nói rõ trang nào, trong quan hệ nào, tại thời điểm nào trong dòng thời gian.
Nếu đọc nó như một cơ chế phục hồi, đó là danh sách các công việc cần làm lại sau khi gặp sự cố. Nhưng nếu đọc nó như một nhật ký giao dịch, nó là một thứ khác: Một bản ghi hoàn chỉnh, có thứ tự, ở cấp độ byte về mọi trang mà cơ sở dữ liệu từng thay đổi, với một tên duy nhất trên mỗi mục nhập.
Cái tên đó, LSN, là phần quan trọng nhất. Nó có nghĩa là dòng thời gian đã có thể truy cập được. Không cần thêm bất cứ thứ gì vào Postgres để biến "cơ sở dữ liệu tại một thời điểm" thành một khái niệm được xác định rõ ràng. Nó chỉ cần một tầng lưu trữ giữ lại nhật ký và có thể trả lời các câu hỏi dựa trên đó.
Nhật ký trở thành nguồn sự thật
Trong một triển khai Postgres thông thường, WAL chỉ là phương tiện để đạt được mục đích. Các tệp dữ liệu là cơ sở dữ liệu, nhật ký bảo vệ chúng, và nhật ký sẽ bị cắt bớt sau khi các bản ghi của nó được áp dụng an toàn. Lưu trữ chỉ đơn giản là một ổ đĩa gắn vào máy chạy Postgres, và mọi thứ về danh tính của cơ sở dữ liệu đều gắn liền với máy đó.
Bây giờ, hãy đảo ngược nó. Hãy biến nhật ký thành cơ sở dữ liệu, và các tệp dữ liệu thành một biểu diễn được dẫn xuất và lưu vào bộ nhớ đệm. Khi đó, bạn có thể giữ toàn bộ dòng thời gian và không còn phải di chuyển dữ liệu để sao chép hoặc tua lại cơ sở dữ liệu. Lịch sử trở nên có thể truy cập được, vì vậy một "bản sao" cơ sở dữ liệu trở thành một con trỏ thay vì một bộ tệp thứ hai. Điều này giúp việc triển khai, khôi phục và tạo bản sao trở nên rẻ đến mức có thể xử lý như mã nguồn.
Đó là những gì chúng tôi đã làm trong Lakebase Postgres. Cụ thể, chúng tôi chia hệ thống thành hai tầng:
Tầng tính toán (compute layer)
Tầng tính toán chạy Postgres tiêu chuẩn. Nó phân tích cú pháp SQL, lập kế hoạch và thực thi các truy vấn, thực thi MVCC, quản lý khóa và chỉ mục.
Không có gì trong công cụ truy vấn bị viết lại. Điều thay đổi là trách nhiệm của nút tính toán: nó tồn tại để thực thi công việc, không phải để bảo tồn dữ liệu. Nó có RAM cho các bộ đệm chia sẻ và NVMe cục bộ làm bộ nhớ đệm trang, và nó có thể khởi động, dừng, mở rộng hoặc ngừng hoạt động bất cứ lúc nào mà không gây rủi ro cho tính bền vững của dữ liệu.
Tầng lưu trữ (storage layer)
Tầng lưu trữ chịu trách nhiệm về tính chính xác, độ bền và lịch sử. Nó tồn tại lâu hơn bất kỳ nút tính toán riêng lẻ nào và được xây dựng từ ba thành phần với các công việc riêng biệt:

Đường ghi (write path)
Đường ghi trông như thế nào? Một lệnh commit trong hệ thống này tuân theo các bước sau:


Thiết kế này có thể gặp một phản đối rõ ràng: bước 2 thêm một bước nhảy mạng (network hop) vào đường commit. Nhưng bất kỳ triển khai Postgres nào coi trọng độ bền đều đã chạy đồng bộ hóa bản sao (synchronous replication), vốn cũng là một bước nhảy mạng. Việc đưa WAL ra bên ngoài chỉ thay thế một vòng lặp mạng này bằng một vòng lặp khác thay vì thêm mới.
Đường đọc (read path)
Mỗi yêu cầu đọc từ một nút tính toán đều mang theo một định danh trang và một LSN, và tầng lưu trữ sẽ trả về trang đó như nó tồn tại tại LSN đó. GetPage@LSN này là một thao tác trung tâm trong kiến trúc này.
Việc phục vụ nó tuân theo thứ tự ưu tiên:
Trang được trả về sau đó sẽ được lưu vào bộ nhớ đệm trong RAM và trên NVMe, vì vậy lần đọc tiếp theo sẽ lại là cục bộ.


Bài viết được AI dịch và tổng hợp tự động từ Databricks: Blog. Liên kết bài gốc ở phía trên. Dữ liệu đồng bộ qua API công khai được ghi nguồn tại AI HOT (canonical) ↗. AIHOT.vn luôn dẫn nguồn đầy đủ — nếu bạn thấy điểm cần chỉnh sửa, hãy gửi ý kiến tại trang phản hồi.