Lessons learned from running GraphQL at scale
Bài tóm tắt Dream11 2021 3. Quy mô lớn Độ khó: Trung bình
Dream11 · 2021 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc
Site chặn crawler; wiki đọc toàn văn qua trình duyệt, ghi chú bằng lời của wiki. Số liệu là theo Dream11.
Bối cảnh
- Dream11 từ 300.000 người dùng (2015) lên hơn 110 triệu (2021), chuyển sang microservice. Khi số service tăng, frontend khó tự gom dữ liệu từ nhiều service, nên năm 2017 dựng một tầng GraphQL (Express.js) đứng trước toàn bộ microservice: gom request mạng, biến đổi dữ liệu cho UI, type safety; web rồi Android, iOS chuyển dần sang. Lượng dùng gấp đôi mỗi năm.
- Traffic theo trận đấu: có thể tăng gần gấp đôi trong hai phút (ví dụ 14 triệu lên 28 triệu lúc 20:00). Các thành phần AWS không autoscale kịp, nên cấp phát load balancer và server theo đỉnh dự đoán, pre-warm load balancer.
- Kiến trúc: máy c5.2xlarge trong Auto Scaling Group, khoảng 7.500 instance cho 1 triệu request/giây; nhiều load balancer (một LB chỉ gắn được số instance giới hạn và là điểm lỗi đơn).
- Các tối ưu đã có: Dataloader gom request trùng giữa resolver; cache hai tầng (server GraphQL và client) theo header X-TTL mỗi API trả về; nhờ GraphQL làm chung xác thực, biến đổi, cache nên microservice phía sau thu nhỏ được.
- Vấn đề: IPL 2020 (Dream11 là nhà tài trợ chính) đỉnh khoảng 40 triệu request/phút, hơn 5,5 triệu người đồng thời; chung kết dùng 13.000 instance sau 13 load balancer. GraphQL thành service đắt nhất với khoảng cách lớn; CPU và RAM tăng vọt ngẫu nhiên (TTL cache client cùng hết, GC, query nặng); deploy trên đội máy đó phức tạp, gần như không thử nghiệm được. IPL 2021 dự đoán traffic gấp đôi.
Thay đổi chính
- Đo trước: môi trường benchmark tổng hợp (mock server giả latency của microservice, client tải tự viết mô phỏng traffic thật). Chỉ số mục tiêu: thông lượng tối đa với p50 dưới 200 ms; các query phổ biến chênh nhau từ 50 tới 500 RPS mỗi server. Trên production đo bằng canary và một chỉ số hiệu năng tự định nghĩa (công việc làm được trên tài nguyên).
- Tìm nguyên nhân: profile CPU lúc cao điểm: khoảng 20% CPU cho GC, bước validate query tốn đáng kể; công cụ Deoptigate chỉ ra hàm megamorphic V8 không tối ưu được; APM theo query (Datadog) cho biết query nào gọi nhiều và gọi bao nhiêu HTTP.
- Kết luận ban đầu: mạng đã tối ưu, CPU là nút cổ chai, không có quả ngọt dễ hái. Chuỗi cải tiến nhỏ:
- Tăng young generation (
max-semi-space-size16 MB → 256 MB, chọn qua load test): CPU production giảm 12%. - Express → Fastify: CPU giảm 10%.
- Bỏ hàm curry của Ramda và code immutable trong đường nóng (benchmark curry chậm tới 100 lần); tách hàm megamorphic thành nhiều hàm monomorphic; resolver lười (chỉ tính khi field được hỏi).
- Cache kết quả parse và validate cho mỗi loại query (production chỉ có một tập query giới hạn); validate từng chiếm khoảng 26% CPU trong load test.
- Hạ tầng: route bằng weighted DNS qua nhiều LB không chia đều vì client cache DNS theo TTL; độ lệch tỉ lệ với số LB và TTL. Bớt server nên bớt được LB, và chỉnh TTL.
- Tăng young generation (
- Kết quả (IPL 2021 so với 2020, theo Dream11): p95 latency giảm 50%, thời gian execute GraphQL giảm 70%; phục vụ 5 triệu người đồng thời với ít hơn 80% instance; chi phí trung bình mỗi ngày giảm 60%, ước tiết kiệm hơn 1 triệu USD trong IPL 2021; GraphQL hết là service đắt nhất.
Vì sao
- Tầng gom dữ liệu đứng trước mọi service phải chịu đỉnh của tất cả, nên mọi phần trăm CPU của nó nhân lên thành hàng nghìn máy.
Bài học cho SWE
- Tầng aggregation (GraphQL/BFF) giữ microservice đơn giản nhưng thành điểm tập trung chi phí và rủi ro; đáng đầu tư tối ưu riêng (Monolith và microservices — đi và quay lại, Chi phí hạ tầng và build vs buy).
- Khi không có quả ngọt dễ hái, cộng dồn nhiều cải tiến nhỏ có đo; cần công cụ đo nhanh trước khi tối ưu.
- Cache kết quả của bước lặp lại trên một tập đầu vào nhỏ (parse/validate query).
- Weighted DNS không chia tải đều vì cache phía client; cùng một TTL hết hạn đồng loạt cũng tạo spike (Hot partition và thundering herd).
- So với Dream11 2021 scale-in/scale-out (cấp phát theo đỉnh dự đoán) (Dream11 2021).
Liên quan
Chi phí hạ tầng và build vs buyMonolith và microservices — đi và quay lạiHot partition và thundering herd
Được nhắc tới trong
Chủ đề (3)
Công ty (1)
Bài tóm tắt (3)