Quản lý fleet và migrate code hàng loạt

Chủ đề Dành cho thành viên
Bài đọc thử: 1/3 · còn 2 bài miễn phí · Xem gói thành viên

Bài toán

Khi số component (repo, service, pipeline, thư viện) tăng nhanh hơn số kỹ sư, chi phí của mỗi thay đổi xuyên suốt (nâng thư viện, vá bảo mật, đổi API nội bộ, khai tử dataset) tỉ lệ với số component chứ không với độ khó của thay đổi. Mỗi team tự làm thì một migration kéo dài nhiều tháng (Spotify: nâng Java mất 8 tháng, khoảng 2.000 PR) và luôn có đuôi dài không ai làm. Bài toán ở đây là đổi đơn vị thay đổi từ "một repo" sang "cả fleet": ai viết thay đổi, máy áp nó thế nào, và vì sao chủ của mỗi repo tin được thay đổi mà họ không viết.

Trang này nói về thay đổi code và cấu hình trên nhiều repo. Migration dữ liệu/hệ thống đang chạy nằm ở Migration không downtime; nền tảng nói chung nằm ở Nền tảng nội bộ cho service (đường ray chung).

Diễn tiến theo thời gian

  • 2012→2024 · Go: đổi một API thư viện chuẩn mà mọi chương trình dùng: sửa v1 tới đâu tương thích cho phép (interface mở rộng, tự seed có cờ GODEBUG quay lại, deprecate để editor gắn cờ), phần còn lại vào math/rand/v2 với đường import riêng để v1 và v2 cùng tồn tại trong một chương trình và chuyển dần; lý tưởng v1 thành lớp bọc mỏng của v2. Go 2024
  • 2012→2025 · Jane Street: hai build system (Jenga nội bộ và Dune do chính họ sinh ra) song song nhiều năm vì migration luôn "năm sau"; chỉ làm được khi có đội 5 người chuyên trách, mất hơn một năm để Dune scale tới 70 triệu dòng và chuyển từng tích hợp editor. Jane Street 2025
  • 2014→2015 · LinkedIn: nâng giao thức Rest.li cho khoảng 100 service bằng một thay đổi cấu hình mỗi service, thư viện client lo phần còn lại. LinkedIn 2015
  • 2018 · Tokio: cải tổ thư viện nền tảng mà ít làm vỡ hệ sinh thái: gom thay đổi phá vỡ thành một đợt sau thời gian dùng thử, facade cho ứng dụng, thư viện chỉ phụ thuộc crate con, mỗi crate con khai báo mức ổn định. Tokio 2018
  • 2019→2022 · Spotify: điều phối 20.000 pipeline batch phát hành dưới dạng thư viện (Luigi, Flo) đóng trong image; user không nâng phiên bản nên nền tảng không đẩy được bản sửa tới hơn 1.000 repo. Chuyển sang dịch vụ Flyte với SDK mỏng: logic ở backend, nâng cấp tập trung. Spotify 2022
  • 2020→2021 · Etsy: monorepo hơn 17.000 file JS chuyển sang TypeScript strict từng file, từng team: công cụ và kiểu cho thư viện dùng chung trước; kiểu API sinh từ OpenAPI; lint cấm ! và as; commit hook chặn người ngoài safelist viết TypeScript trước khi team học xong. Cố ý không dùng công cụ tự chuyển. Cuối 2021: mọi team onboard, khoảng 25% file có kiểu. Etsy 2021
  • 2020 · Figma: bật strictNullChecks cho khoảng 1.162 file (hơn 4.000 lỗi) trong lúc codebase tăng 376 → 464 nghìn dòng: allowlist theo thứ tự đồ thị phụ thuộc (file chỉ vào khi mọi phụ thuộc đã vào; ưu tiên file có nhiều thứ đứng sau), vòng phụ thuộc coi là một nút (vòng lớn nhất hơn 500 file phải phá trước), hai sprint ba ngày với 30 engineer, rồi đổi sang denylist để file mới mặc định strict. Figma 2020
  • 2020 · LinkedIn: reimage hàng chục nghìn server private cloud Rain sang CentOS kernel mới bằng quy trình tự động thay cho các đợt dồn sức toàn đội trước đây; dừng giữa chừng khi một loại phần cứng (HDD) lộ hồi quy, sửa bằng patch kernel thay vì rollback. LinkedIn 2020
  • 2021→2023 · Spotify (Fleet Management): fleet-first: hơn 80% component production được quản lý; BOM Java tự onboard mọi backend và tự merge (96% dùng BOM, 80% bản dưới 7 ngày tuổi); Fleetshift chạy biến đổi code đóng trong image Docker trên Kubernetes, automerger mặc định bật (opt-out), Fleetsweep thử trước khi gửi PR, rollout theo cohort cho pipeline batch. 2022: hơn 270.000 PR, 77% tự merge; framework mới tới 70% service từ khoảng 200 ngày còn dưới 7 ngày; Log4j tới 80% backend trong 9 giờ. Hạ tầng phải khai báo dạng dữ liệu (Kubernetes CRD, khoảng 20 operator) mới thay đổi hàng loạt được. Spotify 2023 Spotify 2023 Spotify 2023
  • 2021 · Vitess: phụ thuộc vào fork Gogo bị bỏ rơi khoá dự án vào Protobuf APIv1; lối ra là công cụ tối ưu dạng plugin chạy cạnh upstream, chỉ sinh helper tuỳ chọn, không sửa struct message. Vitess 2021
  • 2021 · Two Sigma: migration do project manager và bảng tính điều phối thì phạm vi không bao giờ chốt được. ADMIRE: phạm vi là đoạn code chạy hằng ngày trên dữ liệu chuẩn, tự mở/đóng/mở lại ticket Jira cho từng host, service đoán chủ sở hữu, phụ thuộc giữa task, dashboard; ticket thành thước đo chi phí migration. Two Sigma 2021
  • 2022 · eBay: release lại hơn 3.000 thư viện cũ sau khi chuyển sang Maven: dựng DAG phụ thuộc, ưu tiên nút chặn nhiều cha; đổi từ push (service trung tâm kích job Jenkins) sang pull (job tự hỏi việc tiếp theo): từ 2–3 ngày còn khoảng 2 giờ. eBay 2022
  • 2022 · Stripe: Flow → TypeScript cho Dashboard (hơn 3,7 triệu dòng) bằng một PR: codebase gắn chặt nên chuyển dần là phải sống với hai hệ kiểu; codemod (gốc của Airtable) sửa nhiều tháng, lỗi còn lại chèn @ts-expect-error (97.000 → 37.000), khoá monorepo ngày Chủ nhật, chạy lại script và QA ngay trước khi land. Stripe 2022
  • 2022→2026 · Yelp: cùng bài toán Flow → TypeScript nhưng đi từng package (570 package, 1,4 triệu dòng, 3 năm 7 tháng) để không lúc nào mất type checking: flowgen sinh header Flow từ .d.ts làm cầu nối; dogfood 90 package nền trước khi mở; tiến độ tự nguyện chững lại thì chấm điểm package theo đồ thị phụ thuộc và đặt hạn EoL theo quý; phần đuôi đội nền tảng tự chuyển. Yelp 2026
  • 2023→2026 · Yelp: đội Client Data tự nhận toàn bộ migration codegen GraphQL cho monorepo hơn 500 package: fork hai plugin (yarn patch), rồi đẩy ngược lên upstream thành tuỳ chọn chính thức ở GraphQL Codegen v6 để khỏi giữ bản vá riêng; sửa vài trăm lỗi còn lại từng lô (có trợ giúp của AI). Theo Yelp, bắt từng team tự sửa sẽ thành nhiều tháng điều phối; phần khó nhất là tìm chủ sở hữu code qua các lần tái cơ cấu. Yelp 2026
  • 2023→2025 · HRT: đổi ngữ nghĩa import của cả công ty (lazy import trong fork CPython): bắt đầu với team tự nguyện, danh sách loại trừ cho gói bên thứ ba, gộp phần còn lại vào đợt nâng Python 3.12 để không migrate hai lần. Hudson River Trading 2025
  • 2023 · HRT: gỡ tangle trong monorepo Python bằng refactor tự động trên cây cú pháp cụ thể (libcst) + luật phụ thuộc trong CI để không tái phát Hudson River Trading 2023; năm 2024 dùng type annotation để đổi logic nghiệp vụ dùng chung mà type checker chỉ ra chỗ gọi bị ảnh hưởng Hudson River Trading 2024.
  • 2024 · Allegro: hơn 2.000 service; breaking change của thư viện nội bộ được migrate bằng recipe OpenRewrite chạy vào chính PR của Dependabot; tự động 90% là đủ; migration có hạn chót thì force-merge PR đã build xanh. Theo Allegro, ai gây breaking change thì viết cách sửa; niềm tin mất nhanh khi PR khó hiểu hoặc chồng chất. Allegro 2024
  • 2024→2026 · PyTorch: gộp giải mã/mã hoá media trùng lặp ở TorchVision và TorchAudio (nhiều backend, sáu phiên bản FFmpeg) vào TorchCodec, deprecate rồi gỡ API cũ (giữ lại vài API phổ biến sau phản hồi), thu hẹp hai thư viện về transform; ABI ổn định tách lịch phát hành khỏi PyTorch. PyTorch 2026
  • 2025 · Spotify (Honk): dùng lineage trong Backstage, Fleetshift và coding agent chuyển khoảng 1.800 pipeline khỏi hai dataset bị khai tử: 240 PR; bảng ánh xạ trường tường minh; bỏ Scio vì mỗi team viết một kiểu; repo không có test thì phải kiểm tay. Spotify 2026
  • 2025 · Notion: migrate code bằng ratchet: rule ESLint + baseline số lỗi theo file, CI cấm thêm, hạn mức chỉ đi xuống; lỗi đơn giản có autofixer chạy một lần trên toàn codebase, lỗi khó để người hiểu code sửa dần. Đã dùng cho class → function component, bỏ any, bỏ module cũ. Notion 2025
  • 2025→2026 · Allegro: đổi DI của app Android (gần 500 module) từ Koin (nối đồ thị lúc chạy, tới một phần ba cold start) sang Hilt (sinh lúc build): lõi trước, module đã chuyển vẫn có trong Koin dưới dạng proxy, keo tạm cho chiều ngược lại. Quy trình viết thành skill cho coding agent với ví dụ trước/sau và bước build kiểm chứng; thí nghiệm chéo: thời gian developer −76%, tổng −53%. Q2 2026 xong hơn 60 module lõi, còn hơn 400. Allegro 2026
  • 2026 · DoorDash: hơn 60.000 feature flag trên khoảng 623 repo, hơn nghìn flag chết, 2.300 flag mới mỗi tháng. Agent điều phối đọc trạng thái rollout thật qua MCP để đề xuất giá trị đích, người xác nhận, rồi mỗi flag một agent trong git worktree riêng, chỉ mở PR khi build, test, coverage ≥95% và lint qua. 45/50 PR dùng được, 4,79 USD và 13,8 phút mỗi flag, không hồi quy; chỗ hỏng là bỏ sót trong chuỗi gọi dài, không phải sửa sai. DoorDash 2026
  • 2026 · Spotify: Fleet Management đã merge hơn 2,5 triệu PR bảo trì, đa số automerge; script tất định gãy với thay đổi phức tạp nên Honk (coding agent) làm phần sửa code giữa Fleetshift (chọn đích, theo dõi) và CI; một đợt migrate Java trên các backend mất 3 ngày. Spotify 2026
  • 2026 · Uber: JUnit 4 → 5 trên monorepo Java (600.000 test): đưa mọi module lên JUnit Platform chạy cả hai, OpenRewrite qua một Bazel aspect, precondition bỏ file dùng tiện ích chưa hỗ trợ, mỗi target chỉ giữ thay đổi khi build và test qua, Shepherd sinh diff và lặp rollout theo lỗi; 75.000 class, 1,25 triệu dòng, hơn 5.000 diff trong 4 tháng. Thử generative AI cho migration nhưng không thành; theo Uber, cách tất định thực tế hơn. Uber 2026

Các lựa chọn và đánh đổi

Lựa chọn Được Mất Nguồn
Mỗi team tự migrate theo hướng dẫn Không cần công cụ Nhiều tháng, đuôi dài, công lặp lại N lần Spotify 2023
Team gây thay đổi viết bản sửa tự động (recipe/image) Tổng chi phí giảm khi N lớn Thêm việc cho người giữ thư viện; phải học công cụ Allegro 2024, Spotify 2023
Tự merge khi qua test Thay đổi phủ fleet trong ngày Phụ thuộc chất lượng test từng repo; cần theo dõi sau merge Spotify 2023
Rollout theo cohort dựa trên kết quả chạy thật Bắt lỗi mà test trước merge không thấy Chậm hơn; cần hệ đo sức khoẻ (deploy/chạy thành công) Spotify 2023
Thư viện dày vs dịch vụ + SDK mỏng Dịch vụ: nâng cấp tập trung, nhìn được workload Phải vận hành dịch vụ; migrate người dùng sang Spotify 2022
Pull thay push khi phân việc cho worker Ít node, không chờ lập lịch, dùng lại cache Cần service trung tâm giữ hàng đợi eBay 2022
Chuyển từng file, từng team, không công cụ tự chuyển Engineer học qua việc chuyển code quen; ranh giới rõ .ts = đáng tin Chậm (khoảng 25% file sau một năm); phải chuẩn bị kiểu cho thư viện chung, đào tạo, chặn người chưa sẵn sàng Etsy 2021

Quy tắc rút ra

  1. Chuẩn hoá trước, tự động hoá sau: component càng giống nhau (framework, BOM, chuẩn công nghệ) thì thay đổi hàng loạt càng rẻ; phần không chuẩn hoá luôn là đuôi tự động hoá không với tới (Spotify 2023, Honk 2025). Spotify 2023 Spotify 2026
  2. Ai gây breaking change thì viết bản sửa, chạy vào luồng có sẵn (PR của Dependabot, shift hằng ngày) thay vì bắt người dùng học công cụ mới. Allegro 2024 Spotify 2023
  3. Thay đổi không ai review cần test, canary, theo dõi sau merge, và khả năng deploy từ main bất kỳ lúc nào (repave hằng tuần). Spotify 2023
  4. Mặc định bật (opt-out) cộng chỉ số sẵn sàng theo component tạo động lực bổ sung test, thay vì chờ team tự chọn tham gia. Spotify 2023
  5. Cấu hình phải là dữ liệu và nằm trong version control thì máy mới sửa hàng loạt được; nhập được hạ tầng sẵn có mà không đổi nó. Spotify 2023
  6. Thử trên toàn fleet trước khi gửi PR (chạy biến đổi + build trên nhánh tạm) để không làm phiền người khác bằng PR hỏng. Spotify 2023
  7. Hạn chót + force-merge là đuôi của danh sách ngoại lệ co dần khi migration có lý do bảo mật. Allegro 2024
  8. Đo thời gian để một thay đổi phủ X% fleet làm chỉ số tốc độ của nền tảng. Spotify 2023
  9. Trong một repo, ratchet thay cho đợt migrate lớn: baseline số vi phạm, CI cấm thêm, hạn mức chỉ đi xuống, autofixer cho ca dễ, ca khó để người hiểu code sửa dần (Notion 2025). Notion 2025
  10. Một lần hay từng phần tuỳ vào cấu trúc phụ thuộc: codebase gắn chặt, không chia module (Stripe Dashboard) thì một PR được chuẩn bị kỹ rẻ hơn thời kỳ hai hệ cùng sống; codebase chia package (Yelp) thì chuyển dần với cầu nối hai chiều giữ được an toàn suốt quá trình nhưng mất nhiều năm. Stripe 2022 Yelp 2026
  11. Tách "bỏ công cụ cũ" khỏi "sửa hết lỗi": suppression có đếm (Stripe 37.000) hoặc chỉ cho phần đuôi (Yelp khoảng 2.000) để migration kết thúc trong thời hạn. Stripe 2022 Yelp 2026
  12. Khi tiến độ tự nguyện chững lại, dùng đồ thị phụ thuộc để chọn thứ tự và hạn chót theo quý; phần đuôi thường do đội nền tảng tự làm. Yelp 2026
  13. Migration trong suốt: đổi engine, giữ interface (cùng đường dẫn file sinh, cùng tên kiểu) để đội làm migration gánh hết độ phức tạp; bản vá cho công cụ bên ngoài thì đẩy ngược lên upstream thay vì giữ fork (Yelp 2026 GraphQL Codegen). Yelp 2026
  14. Khi migration đổi ngôn ngữ của con người chứ không chỉ của code, rollout theo team với đào tạo là đường găng: chuẩn bị công cụ và kiểu cho thư viện chung trước, mở cho từng team đã học xong (commit hook theo safelist), review mọi PR giai đoạn đầu (Etsy 2021). Etsy 2021
  15. Migration theo đơn vị có phụ thuộc (file, module) đi theo thứ tự đồ thị: phá vòng phụ thuộc trước, allowlist khi phần đã chuyển còn nhỏ, đổi sang denylist khi phần chưa chuyển còn nhỏ để mặc định của code mới đổi theo. Figma 2020 Cùng họ với ratchet của Notion 2025.

Câu hỏi mở

  • Mọi nguồn là tự kể; chưa có nguồn nêu tỉ lệ sự cố do thay đổi tự merge gây ra.
  • Monorepo (Google, Shopify monolith) và polyrepo (Spotify, Allegro) đối xử bài toán này khác nhau; chưa có nguồn so sánh trực tiếp trong wiki. Spotify cho rằng cách làm của họ vẫn áp được nếu chuyển sang monorepo. Yelp 2026 trả lời một phần từ phía monorepo: việc đã gom JavaScript vào một monorepo trước đó cho phép đổi công cụ cho cả hệ sinh thái bằng một PR (thay vì hàng trăm) và chỉ phải lo interop ở mức package Yelp 2026; Yelp cũng cho rằng rollout dần của Rspack dễ hơn nhiều so với nhiều repo Yelp 2026. Vẫn là nhận định một phía, chưa có số liệu so sánh. Ba cách chuyển sang TypeScript (Stripe một PR, Yelp từng package, Etsy từng file theo team) chưa nguồn nào so chi phí hay tỉ lệ lỗi sau chuyển.
  • Coding agent (Honk) mở rộng được tới loại thay đổi nào khi repo thiếu test: Spotify 2025 dừng ở việc để team chủ kiểm tay.
  • Liên hệ: Nền tảng nội bộ cho service (đường ray chung) (nền tảng đẩy mặc định), Migration không downtime (migration hệ đang chạy, danh sách ngoại lệ co dần), Deploy và release an toàn (canary, rollout theo cohort), Tự động hoá vận hành và auto-remediation (operator, reconcile), Pipeline dữ liệu và analytics (khai tử dataset, lineage), CI và build ở quy mô lớn (thay đổi do máy tạo vẫn phải qua CI).
  • Liên hệ: Coding agent trong engineering (migrate, viết lại, chạy song song, quyền hạn) (cổng kiểm tất định, worktree riêng, đặc tả kiểm được bằng máy cho agent).