Making LinkedIn's Organic Feed Handle Peak Traffic

Bài tóm tắt LinkedIn 2018 3. Quy mô lớn Độ khó: Trung bình

LinkedIn · 2018 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc

Bối cảnh

  • FollowFeed (LinkedIn 2016): followfeed-query (broker) gửi song song tới nhiều followfeed-storage rồi gộp. Hai chỉ số QoS: Full QoS (mọi timeline đều trả về) và Partial QoS (có ít nhất một phần dữ liệu); Partial QoS rớt nghĩa là feed chỉ còn nội dung không phải từ mạng lưới.
  • Load test định kỳ một DC ngày 5/2/2018: 10% call không có kết quả, 40% feed bị suy giảm.

Thay đổi chính

  • Nguyên nhân gần: từ thứ Sáu trước, OldGen của vài máy đầy và GC chạy liên tục; replica che được tới khi load test. Heap dump 60+ GB mở bằng Eclipse MAT (Dominator Tree): Jetty ServerConnector giữ khoảng 7,5 GB, 500.000 request đang treo.
  • Hàng đợi quá lớn: request queue của Jetty đặt 5.000. Tính lại: client timeout 400 ms, máy chịu khoảng 1.200 QPS, nên chỉ khoảng 480 request đệm là còn hữu ích; phần còn lại là việc vô ích. Giảm xuống 500. acceptQueueSize đặt 2.000 trong khi mặc định của JRE là 50, đưa về mặc định. Từ chối sớm thì client retry sang replica khác.
  • Retry budget toàn cục thay vì theo host: broker gửi lại sang replica khác sau khoảng 150 ms (median 8 ms, p99 khoảng 100 ms) vì GC pause. Rate limiter cho lần thử 2 và 3 giới hạn tổng ở khoảng 2,5% traffic, nhưng là toàn cục, nên đủ ngân sách để dội gấp đôi tải lên đúng nhóm máy đang yếu. Đổi thành theo host.
  • Các chỉnh khác: kết nối TCP min/max mỗi cặp máy 10/100 → 1/4 (hết spike kết nối gấp 7 lần); timeout HTTP thư viện 3,5 s → khớp timeout ứng dụng 400 ms; thêm rate limit phía server trả 429; cấu hình GC cũ được tune lại.
  • Metric sai: chỉ số QoS đếm lỗi dư 300% vì kiến trúc đã đổi mà cách tính không đổi; viết lại.
  • Việc tiếp theo: mỗi nhóm 4 replica giữ cùng 20 partition nên một máy yếu dồn tải lên đúng 3 máy; đặt partition ngẫu nhiên thì tải dồn lên khoảng 80 máy. Cần headroom test theo service thay vì chỉ phát hiện ở load test toàn site.

Vì sao

  • Các giá trị cấu hình được đặt nhiều năm trước, khi hệ chưa bao giờ chịu tải vượt capacity; không ai còn nhớ lý do.

Kết quả (2018)

  • Qua nhiều load test, cả ở mức cao hơn mục tiêu 10%. Ở DC có cả hai thay đổi, gần như không retry nào bị chặn, chứng tỏ thay đổi Jetty làm tăng capacity thật chứ không chỉ chặn death spiral.

Bài học cho SWE

  • Kích thước hàng đợi hữu ích ≈ capacity × timeout của client; lớn hơn chỉ là RAM, GC và việc vô ích.
  • Ngân sách retry phải tính theo đích, không theo tổng.
  • Timeout của thư viện phải khớp timeout ứng dụng.
  • Metric giám sát cũng cần được kiểm lại khi kiến trúc đổi.

Liên quan