Chat Service Architecture: Persistence
Bài tóm tắt Riot Games 2015 3. Quy mô lớn Độ khó: Trung bình
Riot Games · 2015 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc
Phần 3/3 của series chat League of Legends. Phần 2 (server): Riot Games 2015.
Bối cảnh
- Chat dựng trên ejabberd (mã nguồn mở), vốn chỉ hỗ trợ Mnesia hoặc ODBC. Lúc đầu chọn MySQL vì quy mô chưa là vấn đề và team quen. Mỗi shard ba máy MySQL: primary, backup, ETL. Dữ liệu: danh sách bạn (roster) và metadata, danh sách chặn, tin nhắn offline.
- Khi người chơi tăng, primary quá tải: user không tải được danh sách bạn, không mời bạn được. Ba nỗi đau:
- chỉ scale dọc được (thêm RAM, ổ FusionIO rất đắt);
- primary là single point of failure; trục trặc nhỏ không đủ kích hoạt failover vẫn gây timeout, sự cố lớn thành downtime và nhiều việc tay;
- schema migration ngày càng đắt, thường cần hàng giờ downtime chat theo lịch.
Lựa chọn
Đã xét: shard MySQL ở tầng ứng dụng, MySQL Cluster, Cassandra, Riak. Theo Riot: hai phương án MySQL khó hồi phục nhanh khi replication đồng bộ gặp lỗi; Cassandra khả thi nhưng áp ràng buộc schema họ muốn tránh; chọn Riak (KV, AP theo CAP, scale ngang tuyến tính).
Thay đổi chính
- Đặt Riak trên chính máy chat để rollout nhanh toàn cầu, không phải mua và dựng server mới (cấu hình bằng Chef). Chat server ưu tiên nối Riak cục bộ, tự nối lại node khác nếu mất kết nối, cân kết nối khi topology đổi.
- Backend LevelDB, cho phép nhiều version của một object (
allow_mult = true,last_write_wins = false); replication factor 3–5 tuỳ độ quan trọng (danh sách bạn cao hơn tin offline). - CRDT ở tầng ứng dụng thay cho khoá/2PC: roster lưu kèm mutation log; khi có sibling (hai server cùng sửa danh sách bạn của một người), lần đọc sau gộp log một cách xác định. Ví dụ hai lời mời kết bạn đồng thời đều còn.
- Object mã hoá CRDT → JSON → nén: p95 kích thước từ khoảng 100 kB xuống khoảng 10 kB (object trên 1 MB và "sibling explosion" từng gây downtime).
- Cụm Riak backup đồng bộ bằng Multi Data Center Replication, snapshot định kỳ; snapshot production còn dùng cho load test sát thực tế.
Kết quả (2015)
- 99,9% query Riak khoảng 8 ms (social graph gần như vừa RAM); tải danh sách bạn dưới 10 ms ở 99%.
- Slow query (trên 1 giây) ở shard EUN từ hàng chục nghìn mỗi server xuống dưới 50 mỗi ngày.
- Sau nhiều tháng, một nửa người chơi đã chuyển sang Riak qua hơn chục shard; phần còn lại đầu 2016. Mở khoá push notification cho mobile, danh sách bạn dài hơn.
Bài học cho SWE
- Chọn DB quen thuộc lúc đầu là hợp lý; đổi khi gặp đúng ba dấu hiệu: chỉ scale dọc, SPOF, migration schema tốn downtime (Chọn database theo workload).
- Từ bỏ nhất quán mạnh thì phải trả bằng logic gộp xung đột ở ứng dụng; CRDT trên mutation log là một cách làm việc đó xác định (Giao dịch phân tán và nhất quán xuyên service).
- Đặt kho mới lên phần cứng sẵn có giúp migrate nhanh, đổi lại hai hệ chung tài nguyên.
Liên quan
Được nhắc tới trong
Công ty (1)
Bài tóm tắt (2)