실패를 지배하는 파일럿, 프리펙트(Prefect)는 어떻게 다른가

이동휘·2025년 7월 25일
0

매일매일 블로그

목록 보기
45/49

안녕하세요! 지난 글에서 우리는 데이터 파이프라인의 클래식, 아파치 에어플로우(Airflow)에 대해 깊이 알아보았습니다. 에어플로우는 의심할 여지 없이 강력하고 안정적인 도구이지만, 일부 개발자들은 그의 방식에 몇 가지 불편함을 느끼기 시작했습니다.

"워크플로우를 좀 더 파이썬 코드처럼 자연스럽게 짤 수는 없을까?"
"로컬에서 테스트하는 과정이 너무 번거로워. 실제 배포 환경과 너무 다르잖아."
"실패는 언제나 일어날 수 있는 일인데, 단순히 재시도하는 것 이상의 스마트한 대처는 불가능할까?"

이러한 '불편함(Pain Points)' 속에서, 데이터 파이프라인을 바라보는 새로운 관점을 제시하는 도구가 등장했습니다. 바로 오늘 우리가 깊이 파헤쳐 볼 프리펙트(Prefect)입니다. 프리펙트는 '성공'을 넘어 '실패'를 다루는 방식에 집중하며, 데이터 파이프라인에 '회복탄력성'이라는 새로운 가치를 불어넣습니다. 이 글에서는 프리펙트가 에어플로우와 어떻게 다른 철학을 가졌는지, 그리고 어떤 혁신적인 기능으로 개발자들의 마음을 사로잡고 있는지 상세히 공유하고자 합니다.

1. 핵심 철학: 최첨단 스마트 물류 시스템으로 이해하기

프리펙트란? 예상치 못한 실패를 당연한 것으로 간주하고, 데이터 파이프라인이 어떤 상황에서도 살아남도록 만드는 '회복탄력성'에 초점을 맞춘 현대적인 워크플로우 플랫폼입니다.

에어플로우의 핵심 철학이 "워크플로우를 코드로(Workflows as Code)"였다면, 프리펙트의 핵심 철학은 "네거티브 엔지니어링(Negative Engineering)"입니다. 쉽게 말해, "일이 잘될 때가 아니라, 잘못될 때를 대비하여 시스템을 설계한다"는 뜻입니다.

이 철학을 이해하기 위해, 프리펙트를 '최첨단 스마트 물류 및 배송 시스템'에 비유해 봅시다.

  • 배송 계획서 (Flow): 물건을 어디서 픽업해서 어떤 경로로 전달할지에 대한 전체 계획서입니다. 프리펙트에서는 @flow라는 파이썬 데코레이터 하나로 매우 간단하게 정의됩니다.
  • 개별 배송 단계 (Task): 계획서에 포함된 'A 창고에서 물건 픽업', 'B 분류 센터에서 재포장'과 같은 각각의 단계를 의미합니다. 프리펙트에서는 @task 데코레이터로 정의됩니다.
  • 스마트 관제 시스템 (Prefect Engine & API): 여기가 바로 프리펙트의 핵심입니다! 이 시스템은 단순히 계획서만 따르는 것이 아니라, 수많은 변수에 동적으로 대응합니다.
    • 실시간 교통상황 반영 (동적 실행): 갑자기 길이 막히면(네트워크 지연) 자동으로 다른 길로 우회하거나, 잠시 기다렸다가 다시 출발(자동 재시도)합니다.
    • 배송 사고 감지 및 알림 (실패 처리): 배송 트럭에 문제(Task 실패)가 생기면 즉시 관제탑에 알리고, 정해진 매뉴얼에 따라 예비 트럭을 투입(대체 로직 실행)합니다.
    • 효율적인 경로 학습 (캐싱): 어제 갔던 길인데 변동 사항이 없다면, 굳이 처음부터 경로를 탐색하지 않고 기존의 안전한 경로 데이터(캐시된 결과)를 바로 사용해 시간과 비용을 아낍니다.
  • 중앙 관제탑 대시보드 (Prefect UI / Cloud): 모든 배송 차량의 현재 위치, 상태, 예상 도착 시간 등을 실시간으로 모니터링하는 곳입니다. 문제가 발생하면 왜, 어디서 문제가 발생했는지 상세 로그를 즉시 확인할 수 있습니다.

이 비유처럼, 프리펙트는 정적인 계획을 실행하는 것을 넘어, 예상치 못한 변수로 가득한 현실 세계에서 계획이 끝까지 완수되도록 돕는 동적이고 지능적인 시스템에 가깝습니다.

2. 코드 해독하기: 프리펙트 핵심 개념 Deep Dive

프리펙트의 코드는 놀라울 정도로 파이썬 본연의 모습에 가깝습니다. 에어플로우의 복잡한 객체 선언 대신, '데코레이터'를 활용하여 매우 직관적으로 워크플로우를 구성합니다.

Flow & Task: 파이썬 함수가 곧 워크플로우

프리펙트에서는 일반 파이썬 함수에 데코레이터만 붙이면 바로 워크플로우의 구성 요소가 됩니다.

  • @flow: 워크플로우 전체를 감싸는 컨테이너입니다. 이 데코레이터가 붙은 함수 안에서 Task나 다른 Flow(Subflow)를 호출하여 전체 흐름을 만듭니다.
  • @task: 워크플로우를 구성하는 개별 작업 단위입니다. 재시도, 타임아웃, 캐싱 등의 복잡한 기능을 @task(retries=3, retry_delay_seconds=10, cache_key_fn=...)와 같이 데코레이터의 인자(argument)로 매우 간단하게 설정할 수 있습니다.
# 간단한 Flow 파일 예시 (my_flow.py)
from prefect import flow, task
from typing import List
import httpx # 외부 라이브러리

@task(retries=3, retry_delay_seconds=5)
def fetch_data(url: str) -> dict:
    # API 호출 실패 시 5초 간격으로 3번 재시도
    response = httpx.get(url)
    response.raise_for_status()
    return response.json()

@task
def process_data(data: dict) -> List[int]:
    # 데이터 처리 로직
    return [item['id'] for item in data['items']]

@flow(name="My First Prefect Flow")
def my_data_pipeline(url: str = "http://example.com/api/data"):
    # 일반 파이썬 함수처럼 Task를 호출
    raw_data = fetch_data(url)
    processed_ids = process_data(raw_data)
    print(f"Processed {len(processed_ids)} items.")

if __name__ == "__main__":
    # 일반 파이썬 스크립트처럼 바로 실행해서 테스트 가능!
    my_data_pipeline()

이 코드는 python my_flow.py 명령어로 즉시 실행하고 테스트할 수 있습니다. 이는 에어플로우의 복잡한 로컬 테스트 환경과 비교했을 때, 개발자 경험(Developer Experience)을 극적으로 향상시키는 프리펙트의 가장 큰 장점 중 하나입니다.

3. 무대 뒤의 시스템: 프리펙트의 혁신적인 아키텍처

프리펙트의 아키텍처는 에어플로우와 근본적으로 다른, 매우 중요한 특징을 가집니다. 바로 '하이브리드 실행 모델'입니다.

코드와 인프라의 완벽한 분리: 하이브리드 모델

  • 에어플로우 방식 (Push): 중앙의 스케줄러가 직접 워커에게 "이 작업을 실행해!"라고 작업을 '밀어주는(Push)' 구조입니다. 이로 인해 스케줄러가 워커의 환경에 대해 알아야 하고, 보안 설정이 복잡해질 수 있습니다.
  • 프리펙트 방식 (Pull): 프리펙트의 관제탑(Prefect Cloud/Server)은 절대 여러분의 실제 코드나 데이터를 건드리지 않습니다. 단지 "이제 이 작업을 실행할 시간이야"라는 '명령'만 내립니다. 그러면 여러분의 인프라 안에서 대기하고 있던 '에이전트(Agent)'가 그 명령을 '가져와서(Pull)' 실제 코드를 실행합니다.

이 모델 덕분에, 코드와 데이터는 항상 여러분의 안전한 환경 안에 머물러 있게 되어 보안과 유연성이 크게 향상됩니다.

배포 (Deployment): 코드와 실행 방법을 묶는 레시피

프리펙트 2.0의 가장 혁신적인 개념 중 하나는 '배포'입니다. 이는 단순히 코드를 의미하는 것이 아니라, "어떻게, 언제, 어디서 이 플로우를 실행할 것인가"에 대한 모든 정보를 담은 '레시피'입니다.

하나의 배포에는 다음과 같은 정보가 포함됩니다.

  • 실행할 플로우: 어떤 파이썬 파일의 어떤 flow 함수를 실행할지.
  • 스케줄: Cron 스케줄, 특정 간격(Interval), 이벤트 기반 등.
  • 인프라 정보: 이 코드를 로컬 컴퓨터, Docker 컨테이너, Kubernetes 클러스터 중 어디서 실행할지.
  • 파라미터: 플로우 실행 시 넘겨줄 기본 파라미터 값.

이 덕분에 똑같은 my_flow.py 코드 하나를 가지고, '개발용 배포(로컬 실행)', '스테이징용 배포(Docker 실행)', '운영용 배포(Kubernetes 실행)'를 각각 만들어 관리할 수 있습니다. 코드와 실행 환경이 완벽하게 분리되는 것이죠.

4. 프리펙트, 무엇을 해결했는가?: 탄생의 이유

프리펙트는 에어플로우가 남긴 몇 가지 아쉬운 점들을 정면으로 돌파하며 탄생했습니다.

  • 문제 1: 경직된 워크플로우 → 해결: 동적인 파이썬 네이티브 워크플로우
    에어플로우의 DAG는 한번 정의되면 실행 중에 구조를 바꾸기 어렵습니다. 반면 프리펙트는 일반 파이썬 코드처럼 if/elsefor 루프를 자유롭게 사용하여, 실행 시점의 조건에 따라 Task의 실행 경로를 동적으로 바꿀 수 있습니다.

  • 문제 2: 개발과 운영의 간극 → 해결: 극도로 쉬운 로컬 테스트
    프리펙트는 개발자가 로컬 환경에서 작성한 코드를 거의 그대로 운영 환경에 배포할 수 있도록 설계되었습니다. 일반 파이썬 스크립트처럼 실행하고 디버깅할 수 있어, 개발과 실험의 사이클이 매우 빠릅니다.

  • 문제 3: 코드와 인프라의 결합 → 해결: 안전한 하이브리드 실행 모델
    앞서 설명한 'Pull' 방식의 하이브리드 모델은 코드와 데이터의 보안을 강화하고, 다양한 실행 환경에 유연하게 대응할 수 있는 기반을 마련했습니다.

5. 그래서, 프리펙트를 선택해야 할 이유 (그리고 고려할 점)

프리펙트가 빛을 발하는 순간 (장점)

  • 최고의 개발자 경험: 매우 파이썬답고(Pythonic), 코드가 간결하며, 로컬에서 실행하고 테스트하기가 극도로 편리합니다.
  • 동적 파이프라인의 강자: 실행 시점에 동적으로 변하는 워크플로우, 예를 들어 파라미터에 따라 다른 Task를 실행하는 등의 로직을 매우 쉽게 구현할 수 있습니다.
  • 강력한 내장 기능: 재시도, 캐싱, 동시성 제어 등 실패를 방지하고 파이프라인을 견고하게 만드는 기능들이 매우 직관적이고 강력하게 내장되어 있습니다.
  • 현대적이고 아름다운 UI: 실행 흐름, 로그, 파라미터 등을 한눈에 파악할 수 있는 매우 세련되고 기능적인 UI를 제공합니다.

프리펙트가 어울리지 않을 수 있는 순간 (단점)

  • 상대적으로 작은 커뮤니티: 에어플로우에 비해 역사가 짧아 커뮤니티의 규모나 성숙도가 아직은 작습니다. 특이한 문제에 대한 해결책을 찾기가 조금 더 어려울 수 있습니다.
  • 새로운 개념 학습: 에어플로우에 익숙한 사용자라면 '배포', '에이전트', '워크 풀'과 같은 프리펙트 고유의 개념에 새로 적응해야 합니다.
  • 오픈 소스와 상용 서비스의 경계: 프리펙트는 오픈 소스 코어와 함께 강력한 기능을 제공하는 상용 서비스 'Prefect Cloud'를 중심으로 비즈니스를 전개합니다. 일부 고급 기능(팀 관리, SSO 등)은 유료 플랜에서만 사용 가능합니다.

결론: 파이프라인에 회복탄력성을 불어넣는 현대적인 도구

프리펙트는 똑똑한 스마트 물류 시스템처럼, 단순히 배송 계획서(Flow)를 따르는 것을 넘어, 실시간 교통체증이나 차량 고장(실패)과 같은 온갖 예외 상황에 동적으로 대처하여 어떻게든 물건(데이터)을 목적지까지 안전하게 배송하는 것을 최우선 목표로 하는 현대적인 워크플로우 오케스트레이션 플랫폼입니다.

특히 개발자 친화적인 환경과 파이프라인의 회복탄력성을 중시하며, 복잡하고 예측 불가능한 현대 데이터 세계의 문제들을 해결하기 위해 탄생한 세련된 도구라고 할 수 있습니다.

만약 여러분의 팀이 빠른 실험과 잦은 변경을 필요로 하거나, 개발자의 생산성을 극대화하여 더 창의적인 일에 집중하고 싶다면, 이 똑똑한 파일럿, 프리펙트에게 조종간을 맡겨보는 것은 어떨까요?

0개의 댓글