Carving The Scheduler Out Of Our Orchestrator
Bài tóm tắt Fly.io 2023 4. Điều chỉnh Độ khó: Khó
Fly.io · 2023 · 4. Điều chỉnh · Độ khó: Khó — bài gốc
Bài viết giọng châm biếm, nhiều nhận định là quan điểm của Fly.io (ví dụ về Kubernetes); ghi "theo Fly.io".
Bối cảnh
- Orchestrator về bản chất là supervisor có API: worker nhận việc, chạy, báo lại. Phần được coi là khó là scheduling (chọn worker). Mọi orchestrator phổ biến dùng scheduler tập trung, như bộ cấp phát bộ nhớ, với bức tranh toàn cục về tài nguyên; mặc định là bin packing (dồn việc để dùng ít máy nhất).
- Năm đầu sau khi ra mắt (2020), nền tảng của Fly.io là proxy Rust + driver Nomad (Go): driver chuyển image Docker thành block device rồi chạy Firecracker. Theo Fly.io, Nomad (dựa trên paper Omega: scheduler phân tán, bức tranh tài nguyên nhất quán qua Raft, giao dịch lạc quan) nhẹ và dễ mở rộng, cho họ ràng buộc vùng/cấu hình, rút app khỏi máy để bảo trì, tích hợp Consul. Kubernetes bị loại vì khách muốn chạy app Linux, không phải app Kubernetes.
Vì sao bỏ Nomad (theo Fly.io)
- Bin packing sai mô hình kinh doanh: họ cho thuê máy và đã mua dư ở mọi region; bin packing làm vài máy quá tải hút hết việc ("Katamari Damacy"), hàng xóm ồn, trải nghiệm tệ. Spread chỉ đảo điểm số, không đủ cho kế hoạch đặt việc theo địa lý mà họ muốn.
- Một cụm toàn cầu: Nomad muốn nhiều cụm liên bang theo vùng; liên bang đổi ngữ nghĩa (khó rollback một deploy hỏng trên chục region cùng lúc) và giá license.
- Scheduling bất đồng bộ: gửi job, các server đồng thuận, lên kế hoạch, thử lại tới khi được: ổn cho
flyctl deploy, không dùng được để scale từ 0 khi một request HTTP đến (khởi động máy đồng bộ ở đúng region). Autoscaler lấy metric mỗi 15 giây cộng thời gian scheduling nên không hiệu quả. Phần đắt nhất là kéo image, mà scheduler không coi image đã cache là tài nguyên. - Hành vi "thông minh" phản tác dụng: khi châu Âu mất kết nối tới S3 us-east-1, app chập chờn và Nomad dời chúng sang máy khác.
Thay đổi chính: flyd (AppsV2)
- Mô hình thị trường thay vì bộ cấp phát: yêu cầu là lệnh mua, worker là người bán, orchestrator là sàn. Khớp được thì chạy, không thì thất bại ngay (như lệnh immediate-or-cancel); không có trạng thái pending chờ "chỗ nào cũng được", không tự đổi sang region gần đó.
flydtrên mỗi worker là nguồn sự thật của máy đó: BoltDB dạng log append-only các thao tác; mọi việc là một state machine (tạo máy, xoá volume...) có biểu diễn trong code và trong DB; khởi động lại thì chạy tiếp từ chỗ dở; không cache, mọi thứ đọc từ đĩa khi cần.- Không đồng thuận: các
flydtrong một region không chia sẻ trạng thái. Bức tranh toàn hệ là một view SQLite do Corrosion sinh (gossip SWIM, viết bằng Rust): theo Fly.io, khi mỗi máy tự là nguồn sự thật thì đây là bài toán replication chứ không phải đồng thuận. flaps: proxy không giữ trạng thái gần người gọi; tìm worker trong region qua Corrosion, hỏi năng lực từngflyd(qua mạng WireGuard), xếp hạng best-fit bằng nội suy tuyến tính theo mức dùng tài nguyên.- Đẩy chính sách ra client (end-to-end argument):
flydtự khởi động lại VM chết; còn deploy nhiều region, rollback, máy dự phòng thì doflyctllo (deploy tạo sẵn máy dự phòng trên worker khác, chỉ chạy một; worker chết thìfly-proxybáo khởi động máy dự phòng).
Bài học cho SWE
- Scheduler mặc định tối ưu cho người sở hữu cụm (ít máy nhất); nhà cung cấp nền tảng có mục tiêu khác (dùng đều máy đã mua), nên chính sách đặt việc là lõi sản phẩm, không nên giao cho bin packer chung (Nền tảng nội bộ cho service (đường ray chung)).
- Khi mỗi worker là nguồn sự thật của chính nó, không cần đồng thuận toàn cụm; chỉ cần phát tán trạng thái cho bên đọc.
- Thất bại nhanh và đồng bộ dễ xây hệ phía trên hơn là "sẽ cố gắng" bất đồng bộ; tự động dời việc khi có tín hiệu lỗi có thể làm sự cố tệ hơn (Tự động hoá vận hành và auto-remediation).
Liên quan
#Orchestrator#Scheduler#Nomad#Kubernetes#Borg#Omega#Bin packing#flyd#flaps#Corrosion#BoltDB#State machine#Gossip#End-to-end argument
Được nhắc tới trong
Công ty (1)
Bài tóm tắt (4)