Benchmark PostgreSQL: Một máy chủ duy nhất có thể xử lý 4 tỷ workflow mỗi ngày?
Bài kiểm tra mới đây từ DBOS đã chứng minh khả năng mở rộng ấn tượng của PostgreSQL, với một máy chủ duy nhất đạt tốc độ ghi 144.000 lần mỗi giây. Kết quả cho thấy hệ thống có thể xử lý 43.000 workflow mỗi giây, đáp ứng dễ dàng nhu cầu của hầu hết các ứng dụng hiện nay.

Khi xây dựng các hệ thống thực thi workflow bền vững (durable workflow execution system) trên nền tảng PostgreSQL, câu hỏi phổ biến nhất mà các kỹ sư thường gặp phải là: "Postgres có mở rộng được không?". Mặc dù đã có nhiều bài viết từ các đội ngũ kỹ thuật hàng đầu khẳng định khả năng này, nhưng không phải bài viết nào cũng chỉ ra rõ ràng hiệu suất hoạt động trong thực tế.
Gần đây, đội ngũ phát triển DBOS đã thực hiện một loạt bài kiểm tra độ mở rộng (benchmark) trên một máy chủ PostgreSQL duy nhất để đưa ra câu trả lời cụ thể. Họ tập trung vào hiệu suất ghi, bởi đây là điểm nghẽn chính trong việc thực thi workflow: một workflow bền vững phải ghi vào cơ sở dữ liệu nhiều lần để lưu trữ đầu vào, kết quả và trạng thái của từng bước.
Thiết lập bài kiểm tra PostgreSQL trên AWS
Hiệu suất ghi thô của PostgreSQL
Đầu tiên, họ đo lường thông lượng ghi tối đa mà PostgreSQL có thể duy trì lên một bảng đơn lẻ. Bài kiểm tra được thực hiện trên một phiên bản AWS RDS db.m7i.24xlarge với cấu hình mạnh mẽ: 96 vCPUs, 384 GB RAM và 120K IOPS được cấp phát trên ổ đĩa io2.
Kết quả cho thấy một máy chủ PostgreSQL có thể xử lý tới 144.000 lượt ghi mỗi giây. Con số này tương đương 12 tỷ lượt ghi mỗi ngày — một mức hiệu suất vượt xa mong đợi.
Biểu đồ hiệu suất ghi của PostgreSQL
Tuy nhiên, để đảm bảo họ đã chạm đến giới hạn, đội ngũ DBOS đã phân tích sâu hơn để tìm ra nút thắt cổ chai (bottleneck). Họ phát hiện ra rằng giới hạn không nằm ở CPU hay IOPS, mà nằm ở quá trình flush (đẩy dữ liệu) Write-Ahead Log (WAL) xuống đĩa.
Khi thực hiện thao tác ghi, Postgres không sửa đổi trực tiếp các trang dữ liệu trên đĩa cứng. Thay vào đó, nó ghi mô tả của lệnh ghi vào WAL, sau đó flush WAL xuống đĩa (sử dụng lệnh hệ thống fsync) rồi mới xác nhận hoàn tất cho client. Các tệp dữ liệu thực tế sẽ được cập nhật ở nền sau. Tại bất kỳ thời điểm nào, chỉ có một quy trình đang flush WAL xuống đĩa, trong khi phần lớn các quy trình khác phải chờ khóa WAL. Đây là nút thắt phổ biến đối với các khối lượng công việc ghi dữ liệu cường độ cao.
Hiệu suất Workflow bền vững
Tiếp theo, họ đo lường hiệu suất của các workflow bền vững dựa trên Postgres. Một workflow bền vững thực hiện chính xác hai lượt ghi Postgres: một khi bắt đầu để tạo mục nhập cơ sở dữ liệu, và một khi hoàn thành để ghi lại kết quả cuối cùng.
Kết quả benchmark cho thấy một máy chủ Postgres duy nhất có thể xử lý tới 43.000 workflow mỗi giây. Điều này có nghĩa là việc thêm tính năng bền vững dựa trên Postgres cho một ứng dụng chạy 43.000 workflow mỗi giây sẽ không tạo ra nút thắt hiệu suất.
Tương tự như bài kiểm tra trước, nút thắt vẫn nằm ở WAL: tốc độ Postgres có thể cam kết các giao dịch INSERT và UPDATE của workflow bằng cách flush các mục WAL của chúng xuống đĩa. Sự chênh lệch so với hiệu suất ghi thô (144K so với 86K writes tương đương 43K workflows) là do bảng trạng thái workflow lớn hơn nhiều (31 cột so với 3 cột, 9 chỉ mục so với 1 chỉ mục), yêu cầu flush nhiều dữ liệu hơn.
Hiệu suất Hàng đợi (Queues)
Cuối cùng, họ đo lường khả năng mở rộng của các hàng đợi dựa trên Postgres. Thay vì thực thi trực tiếp, các client sẽ đưa workflow vào hàng đợi Postgres, sau đó các worker sẽ lấy ra và thực thi. Mô hình này yêu cầu bốn lượt ghi Postgres cho mỗi workflow.
Kết quả ban đầu cho thấy một máy chủ Postgres chỉ có thể xử lý 12.100 workflow trong hàng đợi mỗi giây. Lần này, nút thắt không phải là WAL mà là sự xung đột khóa (lock contention) trong bảng workflow_status. Tất cả các quy trình client đều đang enqueue hoặc dequeue từ cùng một vài hàng ở đầu hàng đợi, gây ra sự cạnh tranh giữa chúng.
Kết quả benchmark với hàng đợi Postgres
Để giải quyết vấn đề này, họ đã thử nghiệm phân phối công việc trên nhiều hàng đợi (hoặc nhiều phân vùng của cùng một hàng đợi). Kết quả cho thấy thông lượng workflow tối đa đạt được tăng lên theo số lượng hàng đợi. Cuối cùng, với đủ hàng đợi hoặc phân vùng, các workflow trong hàng đợi đạt được thông lượng 30.600 workflow/giây.
Kết luận
Tổng thể, bài benchmark này cho thấy PostgreSQL mở rộng ấn tượng một cách đáng ngạc nhiên. Chỉ trong một giây, một máy chủ PostgreSQL duy nhất có thể thực hiện 144.000 lượt ghi nhỏ hoặc xử lý 43.000 workflow bền vững. Điều này chuyển đổi thành 12 tỷ lượt ghi hoặc 4 tỷ workflow mỗi ngày — con số quá đủ cho hầu hết các ứng dụng.
Đối với những hệ thống cần hiệu suất cao hơn, khối lượng công việc có thể được phân mảnh (sharding) trên nhiều máy chủ Postgres để xử lý gần như mọi mức tải.


