Sử dụng SQLite làm kho lưu trữ nội dung tĩnh cho máy chủ web
Bối cảnh
- Clace là một nền tảng được thiết kế chủ yếu để cung cấp các ứng dụng web cho công cụ nội bộ.
- Clace cung cấp theo cách tích hợp các chức năng vốn thường được máy chủ web và máy chủ ứng dụng xử lý riêng biệt.
- Ở giai đoạn đầu phát triển Clace, việc quyết định cách lưu trữ dữ liệu ứng dụng và siêu dữ liệu là điều quan trọng.
- Việc lưu siêu dữ liệu trong cơ sở dữ liệu là hợp lý, còn các tệp tĩnh thông thường được lưu trong hệ thống tệp.
Sử dụng SQLite để phục vụ tệp
- Clace đã quyết định dùng SQLite thay cho hệ thống tệp để lưu các tệp của ứng dụng.
- Cách này cho phép thay đổi phiên bản một cách nguyên tử, nhờ đó có thể xử lý nhiều tệp trong một giao dịch khi cập nhật.
- Khi tạo và cập nhật ứng dụng, mọi tệp đều được tải lên cơ sở dữ liệu SQLite; trong chế độ phát triển thì dùng hệ thống tệp cục bộ.
Lợi ích của việc dùng SQLite
- Cập nhật theo giao dịch: Có thể cập nhật nhiều tệp cùng lúc và bảo đảm không có web app bị hỏng trong quá trình cập nhật.
- Rollback triển khai: Có thể rollback bản triển khai khi xảy ra lỗi, và rollback giao dịch cơ sở dữ liệu dễ hơn việc dọn dẹp hệ thống tệp.
- Loại bỏ trùng lặp tệp giữa các phiên bản: Dù cùng một tệp tồn tại ở nhiều phiên bản, nội dung tệp chỉ được lưu một lần.
- Loại bỏ trùng lặp giữa các ứng dụng: Tránh trùng lặp khi nhiều ứng dụng có cùng một tệp.
- Dễ sao lưu: Có thể dễ dàng sao lưu trạng thái hệ thống bằng SQLite.
- Băm nội dung: Khi tải tệp lên sẽ lưu SHA của nội dung để hỗ trợ bộ nhớ đệm trình duyệt.
- Nén: Nội dung tệp được lưu ở dạng nén Brotli và có thể dễ dàng lưu ở nhiều định dạng khác nhau.
Hiệu năng
- Cách tiếp cận truy cập cơ sở dữ liệu SQLite của Clace mang lại hiệu năng rất tốt.
- Do không có triển khai tương đương dùng hệ thống tệp nên chưa thực hiện benchmark trực tiếp.
- Theo benchmark của nhóm SQLite, trong một số workload, SQLite có thể cho hiệu năng tốt hơn hệ thống tệp.
Hỗ trợ đa nút
- Hiện tại Clace chạy trên một nút duy nhất.
- Khi bổ sung hỗ trợ đa nút, họ dự định dùng cơ sở dữ liệu Postgres dùng chung thay cho SQLite cục bộ.
- Điều này có thể gây ra vấn đề độ trễ, và họ dự định dùng cơ sở dữ liệu SQLite cục bộ làm bộ nhớ đệm tệp để giảm độ trễ.
Vì sao cách tiếp cận này không phổ biến
- Lý do hầu hết máy chủ web dùng hệ thống tệp là vì sự tiện lợi.
- Có thể cập nhật tệp bằng các công cụ của hệ thống tệp, còn nếu dùng cơ sở dữ liệu thì cần một giao diện API để tải tệp lên.
Tóm tắt của GN⁺
- Clace là một nền tảng để phát triển và triển khai công cụ nội bộ, tối đa hóa lợi ích của việc lưu trữ tệp bằng SQLite.
- Việc dùng SQLite mang lại nhiều lợi ích như cập nhật theo giao dịch, rollback, loại bỏ trùng lặp và dễ sao lưu.
- Cách tiếp cận này không phổ biến do sự tiện lợi và các lý do lịch sử của hệ thống tệp, nhưng nó nâng cao hiệu quả bằng cách tận dụng hiệu năng và tính năng của SQLite.
- Các dự án có chức năng tương tự được gợi ý gồm Firebase, AWS Lambda.
1 bình luận
Ý kiến trên Hacker News
Vài năm trước, lấy cảm hứng từ bài viết "35% Faster Than The Filesystem", tôi đã thử nghiệm dùng SQLite để phục vụ các tệp tĩnh. Tôi đã tạo một plugin cho phép phục vụ tệp tĩnh từ SQLite qua Datasette, nhưng không dùng nhiều. Nếu muốn phục vụ tệp bằng SQLite, công cụ CLI
sqlite-utils insert-filescó thể hữu ích.Cập nhật theo giao dịch là một ưu điểm lớn vì có thể cập nhật nhiều tệp cùng lúc. Dù máy chủ dùng SQLite hay hệ thống tệp, điều đó cũng không ngăn được ứng dụng web bị lỗi trong lúc cập nhật. Cần bảo đảm mọi tài nguyên con của trang đều được tham chiếu bằng một hash nội dung hoặc tên phiên bản cụ thể.
Khi làm ở một công ty phát triển game nhỏ vào khoảng 2011/2012, chúng tôi lưu toàn bộ asset trong cơ sở dữ liệu sqlite3 và tạo tệp pak để lưu offset của các tệp. Cách này giúp tải asset nhanh trên game di động, đồng thời có thể lưu metadata trong cơ sở dữ liệu để dễ tìm các tệp tương tự.
Dùng SQLite thay cho hệ thống tệp có lợi thế là có thể truy vấn tệp. Có thể viết truy vấn SQL theo kiểu type-safe bằng Kysely.
Ý tưởng phục vụ nội dung tĩnh bằng SQLite không phải là hoàn hảo. Các máy chủ web hiện đại dùng những chiến lược tối ưu nhất để xử lý tệp tĩnh. SQLite có hỗ trợ memory-mapped I/O, nhưng không phù hợp với các website quy mô lớn.
SQLite phù hợp với các website dưới 100K lượt truy cập mỗi ngày. Trang web của SQLite xử lý khoảng 400K~500K yêu cầu HTTP mỗi ngày, và trong đa số trường hợp load average đều dưới 0.1.
CMS dạng static site generator dùng cơ sở dữ liệu SQLite để phát triển và cập nhật website, sau đó dump ra hệ thống tệp thành các trang tĩnh để triển khai.
Trong điện toán khoa học hiệu năng cao, một trong những cách linh hoạt và hiệu năng cao nhất để truy cập dữ liệu thường là dùng cơ sở dữ liệu SQLite chỉ đọc nằm trên RAM disk.
Sẽ rất thú vị nếu so sánh cách tiếp cận này với những trường hợp hệ thống tệp có thể cung cấp deduplication, snapshot, versioning và compression. Nếu dùng hệ thống tệp nâng cao, việc thay thế thư mục bằng phiên bản mới có thể sẽ dễ hơn.
Cách tiếp cận dùng cơ sở dữ liệu như một hệ thống tệp có những ưu điểm riêng, nhưng khi có sự cố xảy ra thì có thể trở thành cơn ác mộng.