Dockerize Apache Airflow: Triển khai CeleryExecutor chuyên nghiệp với Docker Compose

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

Xử lý cơn ác mộng “Dependency Hell” khi cài đặt Airflow

Cài Apache Airflow trực tiếp bằng pip install là cách nhanh nhất để bạn “bay màu” nguyên một buổi chiều. Mình từng kẹt 4 tiếng đồng hồ chỉ vì bản cryptography xung đột với thư viện hệ thống. Airflow không chỉ là một script Python; nó là cả một hệ sinh thái gồm Webserver, Scheduler, Database và Worker.

Vấn đề thường gặp nhất là DAG chạy tốt ở máy local nhưng lại lỗi trên server. Nguyên nhân thường do thiếu thư viện hệ thống cho Google Cloud, AWS hoặc lệch phiên bản PostgreSQL. Quản lý các thành phần rời rạc khiến môi trường cực kỳ mong manh. Chỉ cần một thay đổi nhỏ ở biến môi trường cũng đủ khiến toàn bộ hệ thống lập lịch dừng hoạt động không rõ lý do.

Tại sao cấu hình mặc định không thể dùng cho dự án thực tế?

Mặc định, Airflow sử dụng SequentialExecutor và SQLite làm database. Chế độ này chỉ cho phép chạy đúng một task tại một thời điểm. Thử tưởng tượng bạn có 50 bảng cần ETL mỗi sáng, nếu chạy tuần tự thì đến bao giờ mới xong?

Để đạt hiệu suất thực tế, bạn cần PostgreSQL để lưu metadata và Redis làm hệ thống hàng đợi. Kết hợp với CeleryExecutor, hệ thống mới có khả năng thực thi phân tán. Việc tự cấu hình 5 thành phần này trên hệ điều hành host là một cực hình. Mọi thứ sẽ trở nên chồng chéo, khó debug và gần như không thể đóng gói để bàn giao cho team DevOps.

Ba phương án triển khai Airflow phổ biến

Dân kỹ thuật thường cân nhắc ba hướng đi sau:

  • Cài đặt trực tiếp (Local Install): Chỉ dành cho việc test nhanh vài dòng code. Nó là ác mộng khi cần scale hoặc làm việc nhóm.
  • Managed Services (Astronomer, AWS MWAA): Rất nhàn. Tuy nhiên, chi phí cực cao, không phù hợp cho môi trường lab hoặc startup cần tối ưu budget.
  • Docker Compose: Đây là “điểm ngọt” (sweet spot). Toàn bộ hạ tầng nằm gọn trong một file .yaml, đảm bảo tính đồng nhất 100% từ máy dev đến production.

Giải pháp tối ưu: Dockerize với CeleryExecutor và Redis

Dùng Docker Compose triển khai CeleryExecutor là cách tốt nhất để sở hữu hệ thống lập lịch chuyên nghiệp. Kiến trúc này cho phép bạn mở rộng số lượng Worker linh hoạt để xử lý các tác vụ nặng.

1. Chuẩn bị môi trường

Hãy đảm bảo máy bạn đã có Docker Desktop và Docker Compose v2.0 trở lên. Cấu hình tối thiểu cần 4GB RAM. Tuy nhiên, mình khuyên nên để 8GB nếu bạn định chạy các DAG xử lý dữ liệu lớn.

2. Khởi tạo cấu hình

Đừng tự viết file Compose từ đầu vì rất dễ sai sót biến môi trường. Hãy bắt đầu từ cấu hình chuẩn của cộng đồng. Trước tiên, tạo thư mục dự án:

mkdir airflow-docker && cd airflow-docker
mkdir -p ./dags ./logs ./plugins ./config
echo -e "AIRFLOW_UID=$(id -u)" > .env

Dòng AIRFLOW_UID giúp tránh lỗi permission khi Docker ghi log vào máy host. Đây là lỗi cực kỳ phổ biến khiến nhiều anh em loay hoay cả ngày.

3. Tải file docker-compose.yaml

Lấy file cấu hình chính thức từ Apache Airflow bằng lệnh:

curl -LfO 'https://airflow.apache.org/docs/apache-airflow/stable/docker-compose.yaml'

File này sẽ khởi chạy các dịch vụ quan trọng:

  • postgres: Lưu trữ metadata.
  • redis: Broker chuyển tiếp nhiệm vụ đến worker.
  • airflow-webserver: Giao diện quản lý UI.
  • airflow-scheduler: Bộ não điều khiển toàn hệ thống.
  • airflow-worker: Nơi thực thi code Python thực tế.

4. Khởi tạo Database

Trước khi chạy, bạn cần init database và tạo user admin:

docker compose up airflow-init

Khi thấy dòng exited with code 0, nghĩa là mọi thứ đã sẵn sàng.

5. Kích hoạt hệ thống

Giờ là lúc tận hưởng thành quả:

docker compose up -d

Truy cập localhost:8080 với tài khoản mặc định airflow / airflow. Nếu cần kiểm tra các phản hồi JSON dài từ API Airflow, bạn có thể dùng JSON Formatter để định dạng lại cho dễ đọc, thay vì cài thêm extension nặng máy.

Viết DAG đầu tiên kiểm tra CeleryWorker

Tạo file test_dag.py trong thư mục ./dags để kiểm tra khả năng chạy song song:

from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime
import time

def heavy_task():
    print("Đang xử lý dữ liệu...")
    time.sleep(5)
    return "Done"

with DAG(
    dag_id='test_celery_executor',
    start_date=datetime(2023, 1, 1),
    schedule_interval=None,
    catchup=False
) as dag:

    task_1 = PythonOperator(task_id='run_1', python_callable=heavy_task)
    task_2 = PythonOperator(task_id='run_2', python_callable=heavy_task)

    task_1 >> task_2

Bật DAG trên Webserver và trigger thử. Nếu các task chuyển màu xanh lá cây, hệ thống phân tán của bạn đã chạy chuẩn.

Lưu ý từ kinh nghiệm thực chiến

Để tránh các lỗi “đau thương” khi vận hành, bạn nên chú ý:

  • Resource Limit: Nếu container chết bất thường (Exit code 137), đó là do thiếu RAM. Hãy tăng giới hạn tài nguyên trong Docker Settings.
  • Custom Library: Khi cần dùng pandas hay scikit-learn, bạn phải viết Dockerfile riêng. Hãy FROM apache/airflowpip install thêm thư viện vào image mới.
  • Dọn dẹp Logs: Thư mục ./logs phình to rất nhanh. Hãy cấu hình mount log ra ổ đĩa lớn hoặc thiết lập script tự động xóa sau 7 ngày.

Làm chủ Docker Compose giúp bạn tự tin hơn khi bàn giao dự án. Thay vì gửi tài liệu hướng dẫn dài 10 trang, bạn chỉ cần nhắn đồng nghiệp: “Gõ docker compose up là chạy nhé!”.

Share: