How Discord Stores Trillions of Messages

Bài tóm tắt Discord 2023 3. Quy mô lớn Độ khó: Nâng cao

Discord · 2023 · 3. Quy mô lớn · Độ khó: Nâng cao — bài gốc

Bối cảnh

  • Tiếp nối Discord 2017. Cụm cassandra-messages tăng từ 12 node (2017) lên 177 node, hàng nghìn tỷ tin nhắn (đầu 2022).
  • Hệ thống "high-toil": on-call bị gọi liên tục, latency khó đoán, phải cắt bớt các tác vụ bảo trì vì quá đắt.
  • Ba nguồn đau:
    1. Hot partition: partition (channel, bucket) của server hàng trăm nghìn người nhận lượng đọc lớn; vì đọc/ghi ở mức quorum, latency của một node lan ra cả cụm.
    2. Compaction tụt hậu: đọc đắt hơn, latency dây chuyền. Đội vận hành phải làm "gossip dance": rút node ra cho compact, đưa vào lại, lặp lại.
    3. GC của JVM: pause gây spike, có lúc phải khởi động lại và trông node bằng tay.

Thay đổi chính

  • Đổi engine từng bước: đến 2020 mọi DB khác đã sang ScyllaDB (tương thích Cassandra, viết bằng C++, không GC, shard-per-core). cassandra-messages được để lại cuối cùng để tích luỹ kinh nghiệm vận hành Scylla. Đội ScyllaDB còn phải cải thiện reverse query, vốn là trở ngại cuối cùng.
  • Data services bằng Rust đặt giữa API monolith và DB: khoảng một gRPC endpoint cho mỗi query, cố ý không chứa business logic. Tính năng chính là request coalescing: nhiều user đọc cùng một hàng cùng lúc thì chỉ query DB một lần. Phía trước dùng consistent-hash routing theo channel_id, để mọi request của một kênh tới cùng một instance và coalescing hiệu quả hơn.
  • Migration:
    • Cụm Scylla mới dùng topology "super-disk": Local SSD + RAID mirror sang persistent disk.
    • Kế hoạch đầu: ghi kép, cắt theo mốc thời gian, chép dữ liệu lịch sử bằng Spark migrator, ước tính 3 tháng.
    • Họ viết lại migrator bằng Rust trong một buổi chiều (đọc theo token range, checkpoint bằng SQLite), ước tính còn 9 ngày, tốc độ tới 3,2 triệu tin/giây. Nhờ vậy bỏ được phương án cắt theo thời gian phức tạp.
    • Kẹt ở 99,9999% vì vài token range chứa tombstone chưa từng được compact; compact xong thì chạy hết.
    • Kiểm chứng tự động: gửi một phần nhỏ lượt đọc tới cả hai DB rồi so sánh. Chuyển primary sang Scylla tháng 5/2022.

Kết quả (2022–2023)

Cassandra ScyllaDB
Số node 177 72
Đĩa mỗi node ~4 TB 9 TB
p99 đọc tin lịch sử 40–125ms ~15ms
p99 ghi tin 5–70ms ~5ms

Chung kết World Cup 2022 tạo các đỉnh traffic theo từng bàn thắng, hệ thống chịu được.

Vì sao

Theo Discord: chi phí vận hành Cassandra tăng theo dữ liệu, ngược với kỳ vọng năm 2017. Họ cũng tự nói rõ: chỉ thay DB thì không đủ, vì hot partition vẫn có thể xảy ra trên Scylla, nên phải bảo vệ DB từ tầng phía trên.

Bài học cho SWE

  • Lớp trung gian không có logic (data service) vừa che chắn DB (coalescing) vừa làm điểm xoay khi migrate.
  • Công cụ migrate tốt có thể đổi luôn chiến lược: 3 tháng xuống 9 ngày thì không cần cắt theo thời gian nữa.
  • Nợ dữ liệu cũ (tombstone) lộ ra ở 0,0001% cuối cùng.
  • Dự đoán năm 2017 ("thử Scylla") thành hiện thực sau 5 năm. Ghi lại các phương án dự phòng là việc có ích.

Liên quan