Why Discord is switching from Go to Rust
Bài tóm tắt Discord 2020 3. Quy mô lớn Độ khó: Trung bình
Discord · 2020 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc
Bối cảnh
- Service Read States ghi nhận kênh/tin nào mỗi user đã đọc. Nó nằm trên đường nóng: mỗi lần kết nối, gửi tin hoặc đọc tin đều gọi tới.
- Có hàng tỷ Read State (một cho mỗi user × kênh). Mỗi server giữ LRU cache hàng chục triệu Read State, hàng trăm nghìn lượt cập nhật cache/giây, phía sau là Cassandra với hàng chục nghìn lượt ghi/giây.
- Bản Go (1.9.2; đã thử 1.8–1.10) nhanh phần lớn thời gian, nhưng cứ khoảng 2 phút lại có spike latency và CPU.
Thay đổi chính
- Chẩn đoán: Go ép chạy GC ít nhất mỗi 2 phút dù heap không tăng. Code ít cấp phát nên chỉnh GC Percent vô tác dụng. Spike lớn vì GC phải quét toàn bộ LRU cache để xác định cái gì còn được tham chiếu.
- Vá tạm trong Go: chia nhỏ LRU cache thì spike nhỏ hơn, nhưng p99 tăng vì cache miss nhiều hơn. Họ chọn một điểm cân bằng "tạm chấp nhận" và để vậy một thời gian.
- Viết lại một service bằng Rust (xong bản port tháng 5/2019). Service nhỏ, tự đóng gói, lại là cơ hội để kiểm chứng Rust cho backend. Rust không có GC: Read State bị đẩy khỏi cache thì giải phóng ngay.
- Chấp nhận dùng Rust nightly để có async, cho tới khi async lên bản stable.
- Thả lên một canary node, sửa vài edge case, rồi rollout toàn bộ. Sau đó tăng cache lên 8 triệu Read State (điều Go không cho phép); latency trung bình xuống mức micro giây.
Vì sao
Theo Discord: điểm nghẽn nằm ở mô hình bộ nhớ và GC của Go, không phải ở code. Ngay cả bản Rust chỉ tối ưu sơ bộ cũng đã hơn bản Go tinh chỉnh kỹ; sau khi profile, bản Rust tốt hơn ở mọi chỉ số (latency, CPU, bộ nhớ).
Bài học cho SWE
- Đi tới tận nguyên nhân gốc (đọc source runtime Go) trước khi quyết định viết lại.
- Viết lại đúng một service nhỏ, có số liệu trước/sau và load test. Chính Discord ghi chú: không nên viết lại mọi thứ bằng Rust "chỉ vì thích".
- Bỏ được ràng buộc runtime thì thiết kế cũng thay đổi theo (cache lớn hơn hẳn).
- Bối cảnh tổ chức (theo Discord): 250+ triệu user với dưới 50 kỹ sư, và văn hoá chịu dùng công nghệ mới (Elixir, React Native, Scylla).
Liên quan
- Đổi ngôn ngữ và runtime
- Cache và invalidation
- Discord 2023 (Rust trở thành ngôn ngữ của data service)
- Deploy và release an toàn
Được nhắc tới trong
Công ty (1)