Balancing cost and reliability for Spark on Kubernetes
Bài tóm tắt Notion 2026 3. Quy mô lớn Độ khó: Trung bình
Notion · 2026 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc
Bối cảnh
- Notion chạy nhiều job Spark production, có job vài phút, có job hàng giờ trên hàng trăm worker. Spark chịu được mất một executor (retry task, tính lại), nhưng mất nhiều executor cùng lúc thì mất dữ liệu shuffle, tính lại đắt, retry làm tệ hơn và job hỏng hẳn.
- Trước đó chạy trên EMR với EC2 cố định: cluster hay thừa, dùng ít, phải chỉnh theo từng job, tốn công bảo trì.
Thay đổi chính
- Bước 0, gom về một nền tảng: chuyển sang EMR on EKS: giữ API và công cụ EMR nhưng mọi job chạy trên một nền Kubernetes chung, nên tối ưu chi phí áp được cho tất cả cùng lúc.
- Bước 1, cấp phát động và bin packing: Karpenter (với EKS Auto Mode) chọn loại máy theo CPU/RAM job yêu cầu, bật và tắt node theo nhu cầu; scheduler MostAllocated xếp executor của nhiều job lên node đã có trước khi thêm node. Loại bỏ phần lớn lãng phí hiển nhiên (node rỗi, cluster thừa).
- Bước 2, Spot Instances (rẻ tới 90%, bị thu hồi bất kỳ lúc nào): job thường xuyên hỏng. Nguyên nhân có lẽ là bin packing dồn nhiều executor của một job lên một máy spot lớn; Karpenter quyết ở cấp cluster nên một lần thu hồi giết nhiều executor của cùng một job.
- Thử dựa vào cảnh báo hai phút trước khi thu hồi: Karpenter drain node hợp service stateless, không hợp Spark; tính năng decommission của Spark chép dữ liệu đi không kịp với job lớn. Kết luận của Notion: không phải chuyện cấu hình.
- Spot Balancer: admission webhook của Kubernetes chặn lúc tạo executor và gắn nhãn spot hay on-demand theo tỉ lệ mục tiêu của từng job (ví dụ 70% spot, 30% on-demand), lưu số executor theo loại trong Redis. Một lần thu hồi chỉ mất một phần nhỏ, đã biết trước, số executor; Spark tự retry phần còn lại. Job dài hay quan trọng thì nhiều on-demand hơn.
- Giao diện cho người dùng là vài mức đặt tên (ví dụ
RELIABILITY_OVER_COST) thay cho số từ 0 tới 1, để engineer chọn có chủ ý thay vì luôn chọn mức an toàn nhất. - Kết quả theo Notion: chi phí compute Spark giảm 60–90% tuỳ workload mà không mất độ tin cậy; Spot Balancer được mở mã nguồn cùng AWS.
Vì sao
- Tối ưu ở cấp cluster (bin packing) và tính chịu lỗi ở cấp job (Spark chịu mất ít executor) va nhau: xếp càng chặt thì một lần mất máy càng giết nhiều phần của cùng một job.
Bài học cho SWE
- Gom workload về một nền tảng chung trước, rồi mới tối ưu chi phí một lần cho tất cả (Nền tảng nội bộ cho service (đường ray chung)).
- Dùng capacity rẻ mà dễ mất thì giới hạn phần của mỗi job nằm trên nó, theo đúng mức job chịu mất được (Chi phí hạ tầng và build vs buy).
- Cảnh báo trước khi thu hồi chỉ cứu được tải stateless; tải có trạng thái lớn cần thiết kế ở tầng đặt chỗ.
- Đưa đánh đổi chi phí/độ tin cậy ra giao diện có tên rõ ràng, để chủ job tự chọn và thấy cái giá.
- Cùng hướng với Hotstar 2018 dùng EC2 Spot cho tải chịu được mất máy (Disney Hotstar 2018).
Liên quan
Chi phí hạ tầng và build vs buyNền tảng nội bộ cho service (đường ray chung)Pipeline dữ liệu và analytics
Được nhắc tới trong
Chủ đề (3)
Công ty (1)