- Đang vận hành cụm DB NoSQL (ScyllaDB) xử lý 2 triệu tin nhắn mỗi giây
- Yếu tố ảnh hưởng lớn nhất đến hiệu năng DB là độ trễ của phần cứng đĩa vật lý
→ Ở mức truy vấn thấp thì không thành vấn đề, nhưng khi vượt qua một ngưỡng nhất định, chỉ riêng thời gian đọc 1~2ms cũng đủ khiến hàng đợi đọc trên đĩa hình thành và gây timeout cho chính truy vấn đó
- Độ trễ đĩa thường ở mức micro giây, vậy tại sao thao tác đĩa lại mất 1~2ms?
- Discord vận hành phần lớn hạ tầng trên Google Cloud
- Có hỗ trợ Local SSD dựa trên NVMe, nhưng sau khi tự kiểm thử thì thấy có vấn đề về độ ổn định nên không đủ yên tâm để dùng làm nơi lưu trữ dữ liệu quan trọng
- Persistent Disk có thể gắn/tháo vào máy chủ theo thời gian thực, có thể thay đổi kích thước mà không downtime, luôn có thể tạo snapshot và được thiết kế để sao chép mặc định
→ Vấn đề là nó không gắn trực tiếp vào máy chủ mà được kết nối qua mạng
- Dù độ trễ kết nối mạng nội bộ có thấp đến đâu thì cũng không thể thấp hơn PCI/SATA
→ Mạng là 1~2ms, còn đĩa kết nối trực tiếp là 0.5ms
- Với Local SSD, nếu xảy ra sự cố phần cứng như HDD thì dữ liệu trên đĩa đó sẽ bị mất; nếu chính host gặp sự cố thì thậm chí không thể tạo snapshot, dẫn tới khả năng mất dữ liệu hoàn toàn
→ Vì vậy Discord không dùng Local SSD mà dùng Persistent Disk
Phân tích vấn đề
- Sẽ là tuyệt nhất nếu có một thiết bị lưu trữ kết hợp được mọi ưu điểm của Local SSD và Persistent Disk, nhưng thực tế không có. Vậy nếu chỉ lấy được một phần ưu điểm thì sao?
- Với Discord, độ trễ ghi không phải vấn đề. Thứ ảnh hưởng đến hiệu năng là "độ trễ đọc"
- "Thay đổi kích thước đĩa không downtime" không phải tính năng bắt buộc. Có thể dự đoán kích thước từ trước
- Yêu cầu cuối cùng là
- Vẫn ở trên GCP
- Dùng snapshot Point-in-Time để sao lưu dữ liệu
- Ưu tiên số một là giảm tối đa độ trễ đọc
- Không đánh đổi việc đảm bảo uptime của cơ sở dữ liệu hiện tại
- Có vẻ sẽ tốt nếu đọc dùng Local SSD của GCP, còn ghi thì dùng Persistent Disk
→ Có thể tạo một kiểu "siêu ổ đĩa" như vậy ở cấp độ phần mềm không?
Tạo Super-Disk
- Về cơ bản, yêu cầu là một bộ nhớ đệm ghi xuyên (write-through cache). Dùng Local SSD của GCP làm cache và PD làm lớp lưu trữ
- Máy chủ DB dùng Ubuntu, nên có thể áp dụng cache ở cấp độ đĩa trong kernel Linux (các mô-đun như dm-cache, lvm-cache, bcache)
- Nhưng khi thử nghiệm thì nếu đĩa cache phát sinh bad sector, toàn bộ tác vụ đọc sẽ thất bại
- Khi xuất hiện bad sector thì cần đọc dữ liệu từ lớp lưu trữ rồi ghi đè lại, nhưng các giải pháp cache đĩa đã đánh giá không có chức năng này
- Khi có bad sector, cơ sở dữ liệu sẽ tự shutdown do vấn đề toàn vẹn dữ liệu
- Vì thế phát sinh thêm yêu cầu: "phải sống sót ngay cả khi Local SSD xuất hiện bad sector"
- Do đó họ nghiên cứu "md" của kernel Linux
md hỗ trợ tạo RAID phần mềm
- Chỉ mirror SSD và PD thì chưa giải quyết được vấn đề, vì hơn một nửa lượt đọc sẽ vẫn diễn ra trên PD
md có tính năng write-mostly mà RAID truyền thống không có
- Nếu đặt một đĩa là
write-mostly, nó sẽ bị loại khỏi các lượt đọc thông thường và chỉ được đọc khi không còn lựa chọn nào khác. "Hữu ích với thiết bị kết nối chậm"
- Tức là có thể ghép SSD và PD thành RAID1 rồi đặt PD ở chế độ
write-mostly để đáp ứng yêu cầu
- Vấn đề cuối cùng còn lại là Local SSD của GCP có dung lượng cố định đúng 375GB
- Với một số ứng dụng cụ thể, Discord cần hơn 1TB cho mỗi DB instance
- Vì vậy họ quyết định ghép nhiều SSD thành RAID0
- Cấu hình cuối cùng là
- 4 Local SSD ghép RAID0 thành
md0
md0 và Persistent Disk được ghép RAID1 thành md1
Hiệu năng DB
- Kết quả đúng như dự đoán
- Ngay cả lúc cao điểm, các thao tác đĩa cũng không bị dồn vào hàng đợi và độ trễ truy vấn không thay đổi
- Hiệu năng tăng lên nên lượng truy vấn mỗi máy chủ xử lý được cũng nhiều hơn
- Ai từng dùng RAID có thể sẽ nghi ngờ "liệu cái này có thực sự chạy ổn không?", nhưng trên thực tế đã có nhiều chuyện xảy ra và phần còn lại sẽ được giới thiệu chi tiết ở bài riêng
3 bình luận
Trước đây họ không hài lòng với hiệu năng của golang nên còn viết cả server bằng rust; nhìn vậy mới thấy độ geek của công ty Discord cũng thật đáng nể.
Cảm giác như dùng việc lớn để xử lý chuyện nhỏ.
Trên HN cũng có người nói kiểu như “chẳng phải đây chỉ là vấn đề của GCP thôi sao?”...
https://news.ycombinator.com/item?id=32474093
Dù sao thì cũng có thể xem như một thử nghiệm đáng để biết là hóa ra cũng có thể làm theo cách này.