Airflow & PySpark 개념 정리


Airflow

Airflow에서 모든 워크플로우는 DAG로 표현됩니다. DAG는 순환이 없는 방향 그래프이며, 특정 Task가 다른 Task보다 먼저 수행되어야 한다면 Directed Edge로 순서를 정의합니다.

주요 구성 요소는 다음과 같습니다.

  1. DAG (Directed Acyclic Graph): 워크플로우 전체 구조를 정의하는 그래프로, 태스크 간의 실행 순서와 의존 관계를 나타냅니다. DAG는 순환이 없는 방향성 그래프로, 각 노드는 태스크를 나타내며, 엣지를 통해 실행 순서를 결정합니다.

  2. Task: DAG 내의 개별 실행 단위로, 실제 작업(예: 데이터 처리, 스크립트 실행 등)을 수행합니다.

  3. Operator: 특정 작업을 실행하기 위한 템플릿 클래스입니다. 예를 들어, BashOperator, PythonOperator, SparkSubmitOperator 등이 있으며, 이를 통해 표준화된 작업 실행 방식을 제공합니다.

  4. Sensor: 특정 조건(예: 파일 존재, 특정 이벤트 발생 등)이 충족될 때까지 대기하는 특수한 태스크입니다.

  5. Scheduler: DAG 파일을 주기적으로 스캔하여 태스크를 스케줄링하고 실행 순서를 결정하는 컴포넌트입니다.

  6. Executor: 태스크를 실제로 실행하는 백엔드로, LocalExecutor(단일 머신), CeleryExecutor(분산 환경), KubernetesExecutor(컨테이너 기반 실행) 등이 있습니다.

PySpark

Apache Spark의 파이썬 인터페이스로, 대규모 데이터 처리와 분산 컴퓨팅을 지원합니다.

Architecture

Spark 아키텍처는 다음과 같습니다.

  • Driver: 애플리케이션의 메인 프로세스로, 전체 작업의 제어와 스케줄링을 담당합니다.
  • Executors: 분산 환경에서 실제 작업을 실행하는 워커 프로세스입니다.
  • Cluster Manager: 클러스터 내 자원(메모리, CPU 등)을 관리하며, Spark Standalone, YARN, Mesos, Kubernetes 등 다양한 옵션이 있습니다.

lazy evaluation

Spark는 실제 연산을 바로 수행하지 않고, Transformation을 적용해 DAG(작업 그래프)를 구성한 후, Action이 호출될 때 전체 DAG를 최적화하여 실행합니다. 이로 인해 불필요한 계산을 줄이고 효율적인 실행 계획을 세울 수 있습니다.

Transformation vs. Action

  • Transformation: 새로운 RDD나 DataFrame을 생성하는 연산으로, map, filter, join 등이 있으며, 실제 실행은 지연됩니다.
  • Action: 실제 결과를 반환하거나 데이터를 저장하는 연산으로, count, collect, save 등이 있습니다. Action 호출 시 DAG가 실행됩니다.

PySpark 작업 성능 최적화를 위한 전략(예: 파티션 수 조절, 셔플 최소화, 데이터 스키마 최적화 등)

  • 데이터를 여러 파티션으로 분할하여 작업을 병렬 처리합니다. 파티션 수를 적절히 조절하여 오버헤드를 줄이고, 병렬성을 극대화할 수 있습니다.
  • 셔플 최소화: 불필요한 데이터 이동(셔플)을 줄이기 위해 연산 순서를 최적화하고, repartition(), coalesce()를 사용합니다.
  • 추가 최적화: 데이터 스키마 최적화, predicate pushdown, 캐시 활용 등 다양한 기법을 통해 작업 성능을 향상시킬 수 있습니다.

파티셔닝

  • repartition(): 파티션 수를 증가/감소할 때 사용하며, 풀 셔플(Full Shuffle) 발생.
  • coalesce(): 파티션 수를 감소할 때 사용하며, 셔플 없이 인접 파티션을 병합 (성능 효율적).
  • Too Few Partitions: 병렬성 감소 → 리소스 미활용.
  • Too Many Partitions: 태스크 오버헤드 증가 → 스케줄링 지연.

데이터 스큐(Data Skew) 문제

  • Salting: 임의의 키를 추가해 데이터 분산
  • 파티션 수 조절: 파티션 수를 적절히 조절하여 데이터 분산을 최적화

데이터 크기

  • 권장: 파티션 당 128MB~1GB (HDFS 블록 크기 참고).
  • 계산식: 파티션 수 ≈ (데이터 총 크기) / (128MB)

클러스터 리소스

  • 코어 수: 파티션 수 ≥ 총 코어 수 × 2 (예: 100코어 → 200파티션).
  • 메모리: 파티션 크기가 Executor 메모리를 초과하지 않도록 주의.

메모리 관리 및 캐싱

  • 메모리 관리: Spark는 데이터를 분산 메모리에 저장하여 빠른 연산을 가능하게 합니다.
  • 캐싱/Persistence: cache(), persist() 메서드를 사용하여 자주 재사용되는 데이터셋을 메모리에 저장함으로써, 반복 연산 시 재계산 비용을 절감할 수 있습니다. 이는 작업 성능을 크게 향상시키는 중요한 최적화 기법입니다.



    Enjoy Reading This Article?

    Here are some more articles you might like to read next:

  • Deepseek-R1 모델
  • 학습할때 메모리가 터진다고? Cut Your Losses!
  • GRPO 대신 DAPO: RL 최적화로 LLM 추론 능력 끌어올리기
  • DeepSeek-V3 기술 요약
  • python accelerate 라이브러리 함수 조사기