- rqlite là một cơ sở dữ liệu quan hệ phân tán mã nguồn mở gọn nhẹ, được viết bằng Go và phát triển dựa trên SQLite và Raft
- Việc phát triển bắt đầu từ năm 2014, ưu tiên độ tin cậy và chất lượng; ngay cả sau hơn 10 năm phát triển và triển khai, trong môi trường production cũng chỉ ghi nhận chưa tới 10 trường hợp panic
- Việc kiểm thử hệ thống phân tán đòi hỏi sự cân nhắc cẩn thận ở nhiều lớp, và tuân theo triết lý duy trì chất lượng trong sự đơn giản
Kim tự tháp kiểm thử: cách tiếp cận hiệu quả
- Kiểm thử của rqlite tuân theo "kim tự tháp kiểm thử"
- Kim tự tháp kiểm thử: cấu trúc lấy kiểm thử đơn vị làm nền tảng, bao gồm kiểm thử tích hợp và số lượng tối thiểu kiểm thử end-to-end (E2E)
- Mang lại một bộ kiểm thử hiệu quả, dễ debug và có định hướng mục tiêu rõ ràng
Kiểm thử đơn vị: cốt lõi của chất lượng
- Kiểm thử đơn vị kiểm tra các thành phần độc lập, mang lại sự cân bằng giữa tốc độ và độ chính xác
- Dựa trên SQLite và kiến trúc "shared nothing", phần lớn chức năng có thể được bao phủ bằng kiểm thử đơn vị
- Trong toàn bộ mã rqlite (khoảng 75.000 dòng), kiểm thử đơn vị chiếm khoảng 27.000 dòng
- Các bài kiểm thử hoàn tất trong vài phút, cho phép kiểm thử thường xuyên trong quá trình phát triển
Kiểm thử cấp hệ thống: xác minh đồng thuận
- Kiểm thử cấp hệ thống xác minh sự tương tác giữa mô-đun đồng thuận Raft và SQLite
- Các hạng mục kiểm thử chính:
- Sao chép các câu lệnh SQLite giữa các node
- Các thao tác đọc ở nhiều mức độ nhất quán khác nhau
- Xác minh khôi phục khi cluster gặp sự cố và bầu chọn leader
- Với khoảng 7.000 dòng mã kiểm thử, phạm vi bao phủ toàn diện các tương tác trong cấu hình một node và nhiều node
Kiểm thử end-to-end: lớp tối thiểu
- Kiểm thử end-to-end đóng vai trò là smoke test để xác nhận việc khởi động hệ thống, tạo cluster và các hành vi cơ bản
- Được viết bằng Python và chạy cluster rqlite thực tế để xác minh các chức năng chính
- Ví dụ: xác minh sao lưu lên AWS S3
- Mã kiểm thử được giới hạn ở khoảng 5.000 dòng, sử dụng cách tiếp cận có chủ đích để giảm thiểu chi phí debug
Kiểm thử hiệu năng: thử thách giới hạn
- Kiểm thử hiệu năng đánh giá các chỉ số như sau:
- Tốc độ INSERT tối đa
- Xử lý truy vấn đồng thời
- So sánh mức sử dụng bộ nhớ, CPU và đĩa
- Bao gồm cả việc kiểm thử cơ sở dữ liệu SQLite lớn hơn 2GB để phân tích quản lý bộ nhớ và điểm nghẽn ghi đĩa
- Phát hiện vấn đề hiệu năng và đảm bảo tính ổn định thông qua tối ưu hóa
Những bài học rút ra
- Bắt đầu kiểm thử từ sớm
- Kiểm thử đơn vị là cách hiệu quả nhất để xây dựng niềm tin vào hệ thống
- Không nên trì hoãn việc viết kiểm thử đơn vị trong quá trình phát triển, vì có thể phát hiện lỗi nhanh hơn so với kiểm thử tích hợp hoặc kiểm thử E2E
- Giữ mã kiểm thử đơn giản
- Bộ kiểm thử không phải là nơi để khăng khăng áp dụng các đợt refactor phức tạp hay nguyên tắc DRY (Don't Repeat Yourself)
- Điều quan trọng là viết mã dễ hiểu, và cũng nên chấp nhận thêm cả mã boilerplate nếu cần
- Xác minh chính bài kiểm thử
- Khi viết kiểm thử, hãy tạm thời đảo ngược kết quả mong đợi rồi chạy lại kiểm thử
- Một bài kiểm thử được viết đúng phải thất bại trong trường hợp này, qua đó có thể ngăn ngừa lỗi trong mã kiểm thử từ sớm
- Đừng phớt lờ việc kiểm thử thất bại
- Ngay cả những lỗi kiểm thử hiếm gặp hoặc khó hiểu cũng cung cấp thông tin quan trọng về phần mềm
- Những trường hợp thất bại khó debug thường có thể là cơ hội để phát hiện lỗi nghiêm trọng trong mã
- Tối đa hóa tính quyết định
- Xây dựng cơ chế để có thể chạy thủ công các tiến trình tự động của hệ thống
- Ví dụ: chức năng snapshot của Raft thường chạy bán tự động, nhưng được thiết kế để có thể kích hoạt tường minh trong quá trình kiểm thử
- Thận trọng trong từng quyết định (Be Deliberate)
- Chỉ bổ sung các bài kiểm thử tích hợp cấp cao hoặc kiểm thử E2E khi nhu cầu của chúng được chứng minh rõ ràng
- Kiểm thử quá mức có thể làm chậm tốc độ phát triển và debug
- Áp dụng và lặp lại
- Trong kiểm thử hiệu năng, lời gọi fsync được xác định là điểm nghẽn chính, và các log entry của Raft được nén trước khi ghi xuống đĩa để tối ưu việc sử dụng đĩa
- Đề cao hiệu quả
- Duy trì một bộ kiểm thử có thể chạy trong vài phút để hỗ trợ phát triển lặp nhanh
- Đây là lợi thế thiết yếu cho việc duy trì và duy trì sự năng động của một dự án mã nguồn mở
Chất lượng là ưu tiên hàng đầu
- Tuân theo kim tự tháp kiểm thử, và thiết kế để mỗi lớp kiểm thử có mục đích rõ ràng
- Khi độ phức tạp của hệ thống phân tán tăng lên, việc giữ cho kiểm thử đơn giản là điều then chốt
- Mục tiêu là xây dựng một cơ sở dữ liệu đáng tin cậy và dễ vận hành
1 bình luận
Ý kiến trên Hacker News
Bài kiểm thử đầu tiên là khó nhất nhưng rất đáng để bổ sung. Sau đó các bài kiểm thử sẽ dễ hơn
Sự tận tâm dành cho dự án thật ấn tượng
Mô hình kim tự tháp kiểm thử thì dễ hiểu, nhưng thường thiếu các tầng, nên cần cải thiện nhanh phần này
Có vẻ FAQ bị lỗi copy-paste
Đang mong chờ báo cáo Jepsen
Cũng thích ở định dạng video
Ghen tị với thiết lập kiểm thử hiệu năng
Đã dùng thử rqlite và nó truyền tải rất tốt sự đơn giản
Đang hỏi ý kiến về kiểm thử mô phỏng xác định
Tò mò liệu rqlite có được dùng trong môi trường thực tế hay không
rqlite là một dự án độc đáo và thiên tài