Hybrid Core Allocation: From Overallocation to Reliable Sharing
Bài tóm tắt Uber 2026 4. Điều chỉnh Độ khó: Khó
Uber · 2026 · 4. Điều chỉnh · Độ khó: Khó — bài gốc
Bối cảnh
- Odin là hệ điều phối container cho workload có trạng thái của Uber (database chạy trên đĩa local). Trước đó Odin đã chuyển sang cpuset: mỗi workload nhận trọn các core riêng, giảm throttling và độ trễ, nhưng phải cấp nguyên core.
- Bộ vertical scaler CPU cũ dựa trên ba giả định: đo CPU bằng trung bình 1 phút là đủ, core cấp cho node là riêng không chia sẻ, mục tiêu utilization tự điều chỉnh theo tải failover. Với workload CPU bùng nổ (bursty) thì các giả định này không đủ: cấp theo đỉnh thì lãng phí, cấp theo trung bình thì nghẽn.
Thay đổi chính
- Cấp phát lai (hybrid): mỗi workload nhận một số core riêng (cho nhu cầu ổn định) cộng một phần core chia sẻ (cho đột biến). Core chia sẻ gom thành pool theo host và được cấp vượt (over-allocate) theo một tỉ lệ định trước.
- Khi tranh chấp, Linux
cpu.shareschia thời gian CPU của pool chia sẻ theo kích thước cấp phát. Công thức:cpu.shares = round((core riêng + core chia sẻ) × 100), ví dụ 2 core riêng + 0,5 core chia sẻ → 250. - PoC thực nghiệm: khi ít tranh chấp, scheduler giữ đúng tỉ lệ
cpu.shares; khi tranh chấp nặng thì tỉ lệ thực bị lệch mạnh (khớp với nghiên cứu rkube, SoCC'21). Nên đừng nhét quá nhiều workload đang hoạt động vào cùng một pool chia sẻ. - NUMA: kernel vốn đã ưu tiên bộ nhớ cục bộ nên ghim NUMA tường minh không phải lúc nào cũng cần. Chiến lược: core riêng của một workload nằm cùng một NUMA node, pool chia sẻ trải trên nhiều node. Agent trên host (
odin-agent) cân bằng core chia sẻ đều các node, ưu tiên đặt thêm vào node đã nặng core riêng; không đủ thì trả lỗi và vòng "ensure" thử lại đến khi đạt trạng thái mong muốn. - Scale dọc tại chỗ: chỉnh CPU ngay trên host thay vì dời workload, vì dời một workload có trạng thái nghĩa là chép toàn bộ dữ liệu. Một số workload vẫn phải restart để nhận giới hạn mới, nhưng rẻ hơn nhiều so với chuyển host.
- Scaler mới: core riêng tính theo mức dùng trung bình, core chia sẻ theo độ lệch so với trung bình. Tổng core chia sẻ đã cấp thường lớn hơn số core chia sẻ thật trên host; nhiều đột biến trùng lúc thì vẫn thiếu, nhưng theo Uber hiếm đến mức chấp nhận được.
- Hướng Kubernetes: Kubernetes chưa hỗ trợ cấp phát lai, nên Uber tách code quản lý cgroups thành thư viện riêng và bọc thành plugin CRI.
Giới hạn (theo Uber)
- Quyết định cấp phát đang nằm ở từng host; tốt hơn là đưa lên scheduler có góc nhìn toàn fleet.
- Cấp phát CPU phân mảnh dần sau nhiều lần đặt/dời workload; có thể cần một vòng defrag định kỳ trên agent.
Vì sao
Theo Uber: giảm cấp thừa cho workload bùng nổ, tăng utilization toàn fleet mà vẫn giữ cam kết hiệu năng, hướng tới quản lý CPU "không cần cấu hình".
Bài học cho SWE
- Overcommit là một quyết định xác suất: cấp vượt chỉ an toàn khi các đột biến hiếm khi trùng nhau; phần "riêng" phải đủ cho nhu cầu nền (Chi phí hạ tầng và build vs buy).
- Cơ chế chia sẻ của kernel chỉ công bằng khi tranh chấp nhẹ; đừng coi
cpu.shareslà bảo đảm cứng. - Với workload có trạng thái, scale tại chỗ rẻ hơn rất nhiều so với dời đi; nền tảng nên ưu tiên khả năng này (Nền tảng nội bộ cho service (đường ray chung)).
Liên quan
Được nhắc tới trong
Công ty (1)