Lessons Learned From Running Apache Airflow at Scale

Bài tóm tắt Shopify 2022 3. Quy mô lớn Độ khó: Trung bình

Shopify · 2022 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc

Bối cảnh

  • Shopify chạy Airflow production hơn hai năm (2022) cho trích xuất dữ liệu, huấn luyện model, bảo trì bảng Iceberg, mô hình hoá DBT; Airflow 2.2 trên Kubernetes, Celery executor, MySQL 8.
  • Môi trường lớn nhất: hơn 10.000 DAG, trung bình hơn 400 task chạy cùng lúc, hơn 150.000 lượt chạy mỗi ngày; người dùng tự upload DAG vào môi trường dùng chung.

Thay đổi chính (sáu bài học)

  1. Đọc file chậm trên cloud storage: scheduler liên tục quét và parse lại mọi file DAG. Ban đầu mount GCS qua GCSFuse ở mỗi pod, mỗi lần đọc file là một request GCS: nghẽn. Chuyển sang một NFS server trong cluster (read-write-many) cộng script đồng bộ từ GCS; người dùng vẫn chỉ đụng tới GCS; IAM giới hạn ai được upload (production chỉ qua CD).
  2. Metadata phình làm chậm mọi thứ (UI, và migration khi nâng cấp Airflow mất hàng giờ): một DAG xoá lịch sử quá 28 ngày (đủ cho điều tra sự cố và theo dõi hiệu năng); đổi lại không hỗ trợ tính năng cần lịch sử dài như backfill lâu.
  3. Không biết DAG của ai: người dùng deploy từ repo riêng và sinh DAG lúc deploy, nên thêm manifest khai báo namespace, chủ sở hữu, repo nguồn cho mỗi môi trường.
  4. Tác giả DAG có quá nhiều quyền: DAG policy đọc manifest và từ chối DAG vi phạm: DAG ID phải có tiền tố namespace; task chỉ vào queue Celery và pool được phép; pod chỉ chạy trong namespace và cluster được phép (không đọc secret của namespace khác).
  5. Tải dồn theo đợt: lịch dạng khoảng tuyệt đối (timedelta(hours=1)) khiến hàng loạt DAG sinh tự động cùng chạy một lúc rồi lặp lại đúng chu kỳ; crontab do người viết thì dồn về đầu giờ, nửa đêm. Shopify dùng lịch ngẫu nhiên tất định (băm từ dag_id) cho DAG sinh tự động, đa số workflow; đánh đổi là không phải khoảng nào cũng biểu diễn được bằng một crontab. Tải theo 10 phút phẳng hẳn.
  6. Tranh chấp tài nguyên: pool giới hạn đồng thời theo nhóm task (đồng bộ từ ConfigMap qua PR, không cần quyền admin); priority_weight để DAG giám sát luôn chạy trước (lưu ý trọng số mặc định cộng dồn từ task hạ nguồn nên DAG lớn được ưu tiên); queue Celery và worker riêng cho tải cần môi trường hay tài nguyên khác. Có tài nguyên không chia được theo workload (throughput scheduler, database, IP của Kubernetes) trừ khi tách môi trường.
  • Hướng tiếp: chia workload ra nhiều môi trường Airflow để bền hơn, tinh chỉnh riêng và thu hẹp phạm vi ảnh hưởng của mỗi deployment.

Bài học cho SWE

  • Lịch định kỳ do người hay máy đặt đều tự dồn vào cùng thời điểm; thêm độ lệch tất định theo định danh để san tải, cùng bài học với GitLab 2019 (Hot partition và thundering herd, GitLab 2019).
  • Nền tảng đa tenant cần sổ đăng ký chủ sở hữu và policy chặn lúc nạp thay vì review tay từng job (Nền tảng nội bộ cho service (đường ray chung)).
  • Giới hạn đồng thời theo nhóm (pool) và tách worker là cách cô lập tải trong một hệ chung; cô lập thật sự cần tách môi trường (Load shedding, rate limit và backpressure).
  • Metadata vận hành cũng cần chính sách lưu giữ, nếu không nó làm chậm chính hệ và cả lần nâng cấp.

Liên quan