Slashing CI Costs at Uber

Bài tóm tắt Uber 2025 3. Quy mô lớn Độ khó: Khó

Uber · 2025 · 3. Quy mô lớn · Độ khó: Khó — bài gốc

Bài ngoài sheet. Có paper đi kèm (Juloori & Lin, "CI at Scale: Lean, Green and Fast", arXiv 2501.03440). Bài trước của Uber về SubmitQueue (EuroSys 2019) chỉ có abstract trên blog nên wiki không lấy.

Bối cảnh

  • SubmitQueue giữ mainline luôn xanh (mọi commit đều qua build, unit test, UI test) cho hơn 4.500 kỹ sư, sáu monorepo lớn, bảy ngôn ngữ, hàng chục nghìn thay đổi mỗi tháng.
  • Cách làm: dựng cây suy đoán cho mọi thay đổi đang chờ (mỗi nút là một build của thay đổi trên một tổ hợp các thay đổi phía trước), cắt bớt nhánh nhờ phân tích xung đột (thay đổi độc lập build song song), dùng mô hình xác suất + ML để ưu tiên build có khả năng cần nhất.
  • Hai vấn đề:
    • Tốn tài nguyên: khi thay đổi mới tới có khả năng thành công cao hơn, SubmitQueue huỷ các build đang chạy; ước tính 40–65% build ở các monorepo lớn bị huỷ giữa chừng và phải lập lịch lại.
    • Chờ lâu: xử lý theo thứ tự tới, nên thay đổi nhỏ đứng sau một thay đổi lớn xung đột phải chờ thay đổi lớn xong. BLRD (bypass large diffs) đã giải một phần: nếu mọi build suy đoán của thay đổi nhỏ (có và không có thay đổi lớn phía trước) cho cùng kết quả thì thứ tự là giao hoán, thay đổi nhỏ được land trước. Nhưng các build cần cho BLRD thường không được ưu tiên chạy.

Thay đổi chính

  • Mô hình xác suất mới: mô hình cũ giả định một build đủ quyết định số phận một thay đổi và thay đổi land theo thứ tự tới; BLRD phá cả hai giả định. Mô hình mới: thay đổi có khả năng vượt qua thay đổi lớn thì ưu tiên đều mọi build suy đoán của nó; thay đổi không vượt được thì chỉ chạy nhánh khả dĩ nhất.
  • Dự đoán thời gian build bằng NGBoost (ra phân phối chuẩn có trung bình và phương sai), từ đó tính xác suất thay đổi tới sau sẽ build xong trước thay đổi tới trước.
  • Ngưỡng suy đoán: chỉ build các nút có xác suất được dùng trên ngưỡng. Ngưỡng quá cao thì rẻ nhưng BLRD không chạy được và thời gian chờ tăng lúc tải cao; mô hình mới tăng điểm cho build của thay đổi nhỏ có thể vượt.

Kết quả (theo Uber, 2024, ba monorepo Go/iOS/Android, 21 tuần trước và sau)

  • Số build trên mỗi thay đổi: Go 3,39 → 1,85; iOS 4,93 → 2,57; Android 5,43 → 1,96.
  • Giờ CPU mỗi tuần: Go 1.485 → 821; iOS 472 → 307; Android 729 → 348. Tổng quát: tài nguyên CI −53%.
  • Thời gian chờ P95: Go 33,7 → 18,6 phút; iOS 14,9 → 9,9; Android 25,4 → 17,3. Tổng quát: −37%.

Còn lại (theo Uber)

  • Team lớn hơn và trợ lý code AI làm tốc độ commit tăng, đỉnh vào giờ làm việc ở Mỹ; dù giữ được thời gian build, thay đổi xung đột mới sẽ tới trước khi SubmitQueue xử lý xong thay đổi trước. Họ hẹn bài tiếp.

Bài học cho SWE

  • Hàng đợi merge giữ main xanh có hai chi phí đối nghịch: build suy đoán (tài nguyên) và thời gian chờ; cần đo cả hai.
  • Thứ tự giữa hai thay đổi chỉ quan trọng khi kết quả khác nhau; kiểm được tính giao hoán thì thay đổi nhỏ không phải chờ thay đổi lớn.
  • Huỷ build đang chạy để đuổi theo dự đoán mới có thể tốn hơn lợi ích.

Liên quan