본문 바로가기
E | ngineering

Airflow Design Patterns

by 덞웖이 2025. 3. 25.
댁을 작성하면서 반성하면서 생각한 주제

에어플로 센서와 DAG 작성에 관한 이야기
이하 DAG는 에어플로 DAG를 칭함

Deferrable Operator

기존의 오퍼레이터는, 실행되면 CPU와 리소스를 끝날 때까지 점유.

👉🏿 Polling을 하는 등 대기하는 작업에는 쥐약...

👉🏿 Deferrable Operator는 작업이 바로 끝나지 않더라도, Triggerer 프로세스로 제어권 넘기고, 리소스 반환.

👉🏿 특정 이벤트가 발생하거나 polling 결과가 변화했을 때 컨티뉴.

👉🏿 HttpSensor, S3KeySensor, SQLSensor 요런거.

👉🏿 비동기 방식으로 리소스 사용을 최적화.

👉🏿 커스텀 트리거를 만들어서, 커스텀 오퍼레이터에서 사용하면 커스텀 센서를 만들 수 잇다. execute 메소드를 활용하는/안하는 방법이 있는데, 그건 똑큐먼트를 찾아보자...


Operator Pattern과 Event-driven 패턴

🍕 Operator Pattern

👉🏿 모든 작업은 Operator의 인스턴스가 정의하고, 각각의 Operator는 하나의 작업만을 수행해야 함.

👉🏿 즉, DAG 안에서 복잡한 비즈니스 로직을 작성하거나, if-else 문으로 흐름을 분기하면 ❌.

👉🏿 그런 건 따로 분리하고, 인자값과 함께 Operator를 호출만 하는 식으로 설계해야 함.

🍔 Event-driven Pattern

👉🏿 S3에 파일이 생기면 시작하는, Kafka 토픽에 메시지가 들어오면 트리거 되는 파이프라인 등.

👉🏿 시점에서 볼 떄, Deferrable Operator나 External Trigger등은 이걸 따라가려고 도입함.

👉🏿 그래도 Schedule 기반! 완전한 이벤트 드리븐 패러다임으로 구현하기엔 무리.

👉🏿 는 polling 등으로 체크하는 pull-base 라는 점과 카프카, 람다 등은 이벤트에 반응하는 push-base라는 점.


그래도 로직이 넣구싶어요

DAG는 워크플로우를 정의하는 블루프린트임.

여기에 빋닏 로직을 직접 넣기 시작하면...🤪

☝🏿 테스트: 로직에 대해서 유닛 테스트 어터게 할거임?

🤞🏿 재사용성: 로직이랑 댁이 결합도가 높은식으로 만들면, 오퍼레이터 날마다 맹글어야겟네?

🤟🏿 가독성: 스압... ctrl + f 로 찾는것도 한계가 잇찌 🤮

로직은 별도의 Python 모듈로 작성하고 DAG에서 모듈 import하고... 그렇게는 하지 맙시다 😇

하지마 제발 (나한테)


구럼 쏀써 사용은 철학에 어긋나니 쓰면 안되나

센서 사용 자체가 잘못된 것은 아니지만,

가능하면 Deferrable Sensor를 써서 리소스 아끼기

한 DAG가 다른 DAG 실행 여부를 감시/기다리는 구조 피하기

디자인 철학 중 하나인 DAG 간의 독립성을 고려했을 때,
DAG가 다른 DAG의 상태나 결과를 알아야 한다면,
DAG간 결합도가 높음을 의미,
전체 시스템 복잡도가 높아짐.

API 호출로 다른 DAG를 트리거하거나, 메시지 브로커를 사용해서 트리거할 수 있다면 (일적으로 오버헤드가 증가하긴 하지만...) 더 자연스러워지지 않을까유💤


TL;DR

설계와 운영 원칙

  1. 워크플로우와 비즈니스 로직의 분리.
  2. Deferrable Operator로 리소스 최적화. reschedule!!
  3. 센서 사용은 필요할 때만, 가능하면 이벤트 기반으로.
  4. DAG간의 의존(결합)을 최소화, 시스템 확장성과 유지보수 고려.

👿 안 그러면 복잡해진 DAG를 보면서 울고 리뷰어의 철퇴를 맞을것임. 🔨

👋🏿

'E | ngineering' 카테고리의 다른 글

해시와 해시충돌  (0) 2025.04.06
TLS, 통신, 무념무상  (0) 2025.03.28
위상 정렬과 DAG  (0) 2025.03.12
Mixin 으로 객체로운 생활  (0) 2025.03.11
B쁠러쓰마이나쓰Tree  (0) 2025.03.05