Rethinking Netflix's Edge Load Balancing

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

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

Bối cảnh

  • Cloud Gateway (Zuul) nhận hơn 1 triệu request/giây (2018). Zuul dùng Ribbon round-robin + loại server có tỉ lệ lỗi kết nối cao, kèm vài tuỳ biến bớt traffic cho server mới khởi động; một số cụm origin vẫn có lỗi do quá tải cao.
  • Thường chỉ một phần server quá tải: server lạnh sau khởi động (red-black deploy, autoscale), server chững lại vì cập nhật property/dữ liệu hoặc GC lớn, phần cứng tồi hoặc hàng xóm ồn.

Thay đổi chính

  • Nguyên tắc: làm trong khung load balancer có sẵn để đội khác dùng lại (tuỳ biến cũ gắn chặt vào Zuul); học từ cách đã thử ở stack IPC khác; tránh state phân tán, quyết định cục bộ; tránh cấu hình phía client và chỉnh tay (cấu hình đặt ở client của đội khác sẽ lệch với thực tế server), ưu tiên cơ chế thích nghi, ngưỡng tĩnh thì để server báo lúc chạy.
  • Ý chính: client thấy rõ nhất latency của server, server biết rõ nhất utilization của chính nó; kết hợp cả hai.
  • Join-the-shortest-queue riêng lẻ trên nhiều load balancer gây herding (cùng chọn server ít tải rồi đè nó), và mỗi LB chỉ thấy phần kết nối của mình (thường "chọn giữa 0 và 0"). Chia sẻ state giữa các LB thì phải giải bài toán state phân tán (vận hành, bán kính hỏng khi dữ liệu sai, chi phí DB).
  • Server tự báo utilization qua header response X-Netflix.server.utilization (số request đang xử lý / mức tối đa, kèm target tuỳ chọn); thụ động theo response thay vì poll health-check. Thử CPU và load average thì dao động vì là trung bình trượt có độ trễ.
  • Choice-of-2 thay round-robin: chọn ngẫu nhiên hai server, so điểm gộp từ ba yếu tố: sức khoẻ phía client (tỉ lệ lỗi kết nối), utilization server báo, số request đang gửi từ LB này. Không dựa một yếu tố: server hỏng từ chối nhanh sẽ báo utilization thấp và hút thêm traffic.
  • Lọc mỗi request các server vượt ngưỡng utilization/sức khoẻ (best-effort N lần rồi bỏ lọc); probation: server chưa trả lời lần nào chỉ được một request đang chờ; warmup tăng dần trong 90 giây đầu; decay thống kê về 0 trong 30 giây để server không bị loại vĩnh viễn.
  • Load test tổng hợp (Zuul 200 node → origin 20 instance + nhóm 20 instance chậm): giảm load-shedding và lỗi kết nối nhiều bậc độ lớn so với round-robin, latency trung bình và đuôi giảm khoảng 3 lần; riêng utilization do server báo đóng góp một bậc giảm lỗi và phần lớn giảm latency. Nhóm chậm chỉ nhận khoảng 15% traffic thay vì 50%.

Vì sao

  • Ở quy mô hơn một triệu request/giây, tỉ lệ lỗi thấp vẫn ảnh hưởng nhiều hội viên; định tuyến quanh server suy giảm tự động đỡ phải đánh thức người trực.

Bài học cho SWE

  • Tác động vận hành: phân phối request không còn đều nên canary phải so RPS kèm CPU; nhóm deploy mới có regression nhận dưới 50% traffic; phát hiện server lạc loài khó hơn vì chúng nhận ít traffic.
  • Kết hợp tốt với cập nhật dữ liệu cuốn chiếu trong cụm: LB tạm giảm traffic tới vài server đang áp cập nhật (thường gây GC).
  • Alert theo tỉ lệ lỗi bị mù: LB giữ lỗi thấp nên vấn đề lớn trên một phần cụm không còn kích alert; phải thêm alert theo độ lệch utilization.

Liên quan