4 hệ quản trị cơ sở dữ liệu trên cùng một máy chủ: SQLite hay PostgreSQL thực sự làm chủ cuộc chơi?

vibecode

Administrator
Tác giả Arjay McCandless đã dựng một máy chủ VPS chỉ 12 USD (1 CPU chia sẻ, 2 GB RAM, 50 GB SSD) chạy chung cả ứng dụng backend Go lẫn cơ sở dữ liệu để so sánh hiệu năng giữa PostgreSQL, MySQL, MariaDB và SQLite qua công cụ K6. Kết quả cho thấy SQLite áp đảo ở tác vụ nhiều lượt đọc (read-heavy) với hơn 13.400 người dùng đồng thời nhờ kiến trúc thư viện nhúng không tốn chi phí giao tiếp tiến trình, nhưng lại sụt giảm nghiêm trọng khi chuyển sang ghi nhiều (write-heavy) ở chế độ bảo toàn dữ liệu nghiêm ngặt do giới hạn đơn luồng ghi (single writer). Ngược lại, MariaDB vượt trội MySQL khoảng 40% tải phục vụ do mức tiêu thụ I/O ghi đĩa mặc định thấp hơn rất nhiều.

=========================

Chào mọi người, anh chị em làm kỹ thuật chắc hẳn ai cũng từng đau đầu cân nhắc giữa PostgreSQL, MySQL hay tự hỏi liệu SQLite có đủ sức gánh vác các dự án thực tế khi chạy trên các máy chủ cấu hình khiêm tốn hay không. Mới đây, một thử nghiệm thực tế rất trực quan và thú vị của Arjay McCandless đã đưa ra những con số cụ thể giúp chúng ta có góc nhìn rõ nét hơn.

Thiết lập môi trường thử nghiệm​


Toàn bộ hệ thống được chạy trên một máy chủ duy nhất có cấu hình 1 shared CPU, 2 GB RAM và 50 GB SSD. Ứng dụng là một API mạng xã hội cơ bản viết bằng Go, xử lý các thao tác tải bảng tin (feed), mở bài viết, bấm thích và tạo bài viết mới. Cả ứng dụng Go và database đều nằm chung trên một máy chủ, không tách riêng máy chủ cơ sở dữ liệu độc lập. Dữ liệu khởi tạo đồng nhất cho cả 4 hệ thống gồm 50.000 người dùng, 500.000 bài viết và hơn 2 triệu lượt tương tác thích. Tác giả dùng công cụ K6 trên một máy chủ khác để bắn tải giả lập với tiêu chí vượt qua bài kiểm tra: duy trì ổn định trong 5 phút, độ trễ P95 dưới 500ms, P99 dưới 1 giây và tỷ lệ lỗi dưới 1%.

Kịch bản đọc nhiều (Read-heavy, khoảng 8% ghi)​

Đây là kịch bản mô phỏng sát với hành vi người dùng thông thường của một ứng dụng mạng xã hội:​

​

    • PostgreSQL: Trụ được tối đa 6.350 người dùng đồng thời, xử lý khoảng 600 requests/s. Lúc này PostgreSQL chiếm khoảng 60% CPU và ứng dụng Go chiếm khoảng 23% CPU.
    • MySQL: Đạt 6.650 người dùng đồng thời, nhỉnh hơn PostgreSQL khoảng 5%, CPU phân bổ khoảng 50% cho MySQL và 28% cho Go.
    • MariaDB: Gây bất ngờ lớn khi vượt qua mốc 9.300 người dùng đồng thời, cao hơn gần 40% so với MySQL dù dùng chung driver kết nối tương thích. Phân tích sâu hơn ở cùng mức tải 2.000 người dùng cho thấy MariaDB tiêu tốn ít hơn từ 24% đến 29% CPU cho mỗi request so với MySQL. Đáng chú ý nhất là mức độ ghi đĩa: MariaDB chỉ ghi khoảng 56 KB/s trong khi MySQL ghi tới 701 KB/s (gấp 9 đến 14 lần), một phần do MySQL bật mặc định performance_schema cùng các cơ chế I/O mặc định khắt khe hơn.
    • SQLite: Nhờ kiến trúc thư viện nhúng trực tiếp vào tiến trình ứng dụng Go, loại bỏ hoàn toàn chi phí kết nối mạng hay giao tiếp giữa các tiến trình (IPC), SQLite đạt tới 13.400 người dùng đồng thời và xử lý khoảng 1.800 requests/s, gấp đôi tải so với PostgreSQL.

Kịch bản ghi nhiều (Write-heavy, khoảng 43% ghi) và bài toán đánh đổi​


Khi điều chỉnh kịch bản để tăng tỷ lệ ghi bằng cách cho người dùng bấm thích và tạo bài viết liên tục, nút thắt cổ chai (bottleneck) của toàn hệ thống lập tức chuyển từ năng lực tính toán CPU sang thời gian chờ I/O đĩa:

    • PostgreSQL giảm từ 6.350 xuống 3.850 người dùng đồng thời.
    • MySQL giảm từ 6.650 xuống 3.150 người dùng đồng thời.
    • MariaDB giảm từ 9.300 xuống 5.000 người dùng đồng thời.
    • SQLite: Ở chế độ mặc định Write-Ahead Logging (WAL) với cấu hình synchronous=NORMAL, SQLite vẫn đạt 6.800 người dùng. Tuy nhiên cấu hình này có một điểm trừ là nếu toàn bộ máy chủ bị mất điện đột ngột, các commit gần nhất có nguy cơ mất mát dữ liệu.
      Khi tác giả thiết lập SQLite về mức an toàn cao nhất synchronous=FULL (buộc phải fsync mỗi lần commit xuống đĩa như các cơ sở dữ liệu máy chủ truyền thống), hiệu năng của SQLite sụp đổ hoàn toàn, chỉ còn chịu được 1.550 người dùng đồng thời và máy chủ dành gần 40% thời gian chỉ để chờ I/O đĩa. Lý do là SQLite tại một thời điểm chỉ cho phép đúng một luồng ghi (single writer lock) và phải đợi đĩa quay vòng sync xong, trong khi PostgreSQL, MySQL hay MariaDB sở hữu cơ chế gom nhóm commit (group commit) cho phép nhiều giao dịch ghi đồng thời chia sẻ chung một lần xả dữ liệu xuống đĩa.

Mở rộng khối lượng dữ liệu (Data volume test)​

Khi tăng lượng dữ liệu khởi tạo lên gấp 10 lần (500.000 người dùng, 5 triệu bài viết, 20 triệu lượt thích, dung lượng thô tăng từ 155 MB lên khoảng 1,6 GB), thứ tự xếp hạng vẫn không có nhiều biến động: SQLite dẫn đầu ở 14.500 người dùng, tiếp đến là MariaDB (8.000), MySQL (6.000) và PostgreSQL (5.000).

Bài học rút ra cho kiến trúc ứng dụng​


Thử nghiệm này cho thấy nếu anh chị em xây dựng một hệ thống nhỏ gọn, monolithic, đóng gói trọn gói ứng dụng và cơ sở dữ liệu trên một máy chủ duy nhất để tối ưu chi phí hạ tầng, SQLite thực sự là một lựa chọn cực kỳ mạnh mẽ cho các tác vụ thiên về đọc.

Tuy nhiên, với các hệ thống phân tán, production quy mô lớn đòi hỏi tính khả dụng cao, PostgreSQL, MySQL hay MariaDB sinh ra để phục vụ bài toán hoàn toàn khác.

Các tính năng như nhân bản dữ liệu (replication), cụm máy chủ chịu lỗi (clustering, Galera Cluster, InnoDB Cluster), khả năng gom nhóm commit ghi đồng thời và cơ chế chuyển đổi dự phòng khi máy chủ chính gặp sự cố chính là những giá trị cốt lõi bù đắp cho phần chi phí tài nguyên phát sinh.

Không có công nghệ nào là hoàn hảo tuyệt đối cho mọi bài toán, việc hiểu rõ bản chất kiến trúc và đặc thù tải đọc/ghi của ứng dụng sẽ giúp bạn chọn đúng công cụ ngay từ đầu. Mọi người thường ưu tiên lựa chọn cơ sở dữ liệu nào cho các dự án chạy máy chủ độc lập của mình?

1791575458165.png

1791575472795.png

1791575482528.png1791575489855.png

1791575498956.png

1791575508189.png1791575515434.png1791575523789.png
 
Back
Top