장점: 작업 중심 흐름 정의, 빠르게 발전하고 있음, 쿠버네티스 없이 실행될 수 있음, 로컬 환경에서 실행될 수 있음, 충분한 기능들을 가짐, 설치가 쉬움, airflow에 비해 상대적으로 간단함. 단점: 버그가 많음.
플로우(flow): 입력과 출력을 가진 하나의 함수이다.
데코레이터 @flow
를 이용해 정의된 하나의 함수이다. 데코레이터는 retries
, retry_delay_seconds
, log_prints
등 옵션을 제공한다. 각각이 무엇을 의미하는지는 충분히 직관적이다. prefect에서 제공하는 로거를 사용하지 않으면 표준 출력은 터미널로 출력되지 않는다. 플로우를 실행하려면 그냥 데코레이팅된 함수를 호출하기만 하면 된다.
파라미터(parameters): 플로우에 입력되는 위치 인자와 키워드 인자를 의미한다. prefect는 타입 힌트를 바탕으로 파라미터 타입을 강제하는 기능을 가지고 있다.
아티팩트(prefect artifact): 메트릭, 출력, 로그 등을 저장하는 공간.
서브플로우(subflow): @flow
데코레이팅된 함수가 @flow
데코레이팅된 또다른 함수를 호출하는 것도 가능하다. 네스팅된 플로우가 실행되는 경우 웹 콘솔에 아래와 같이 시각화된다.
작업(task): 입력과 출력을 가진 하나의 함수이다. 작업들을 연결하면 플로우가 된다.
@task
를 이용해 정의된 하나의 함수이다. 어떤 함수가 작업으로 데코레이팅되면, 함수의 입출력이 캐싱되어 나중에 플로우의 일부만을 재실행하는 일에 도움이 된다. 멤버 변수같은 값에 조회를 할 수 있다면 재현이 어렵기 때문인지 함수가 아닌 메서드를 작업이나 플로우로 등록하는 것은 불가능하다. 데코레이터는 cache_key_fn
(캐시 여부 결정을 위해 해시값과 같은 정보를 입력한다. You can define a task that is cached based on its inputs by using the Prefect task_input_hash
.), cache_expiration
등 옵션을 제공한다. 이것도 옵션 각각이 무엇을 의미하는지 이해하기 쉽다. 캐싱한 실제 데이터는 ~/.prefect
디렉토리에 저장된다. 작업을 실행하려면 그냥 데코레이팅된 함수를 호출하기만 하면 된다.submit
메서드를 호출하고, 이때 받은 객체에 result
메서드를 호출하여 작업이 완료되어 값을 받기까지 대기한다.플로우 배포(deployment): 기능적 관점과 생산자 관점에서 바라볼 수 있다. 기능적 관점에서, 플로우 배포는 플로우를 관리할 수 있는 API를 생성하는 일이다. 생산자 관점에서, 플로우 배포는 어떤 환경에서 어떻게 실행될 것인지를 정의하는 일이다.
생산자 관점에서, 플로우를 배포하려면 @flow
로 데코레이팅된 플로우 객체에 serve
메서드를 호출한다. serve
메서드가 호출되는 순간 스크립트는 무한 루프에 빠져(long-running process) 플로우와 관련된 다양한 요청(request)을 기다린다. 만약 serve
메서드에 의해 곧바로 무한루프에 빠지는 것이 싫다면, to_deployment
메서드와 serve
함수를 사용하면 된다. 무한 루프에 빠져 대기하고 있는 플로우를 잠자는 배포(sleeper deployment)라고 한다.
기능적 관점에서, 특정 플로우를 위한 API가 생성된다는 것은 해당 플로우를 원격에서 실행, 재실행, 중단, 일시정지, 파라미터 변경 등이 모두 가능해진다는 것이다. 플로우를 CLI를 이용해 실행하려면 prefect deployment run '<플로우이름>/<배포이름>'
을 입력하면 된다.
배포된 플로우를 실행하는 방법은 다양하다. 파라미터의 타입이 데이터클래스를 이용해 다음과 같이 정의되어있을 때,
@dataclass(eq=False, repr=False)
class DataInfo(betterproto.Message):
object_storage_urls: List[str] = betterproto.string_field(1)
dataset: str = betterproto.string_field(2)
@prefect.flow
def server_flow(data_info: DataInfo) -> Response:
...
# ...
server_flow.serve(name="PrefectDeployer")
웹 UI
CLI
prefect deployment run server-flow/MyPrefectDeployer --param data_info='{"object_storage_urls": ["a"], "dataset": "b"}'
관리형 prefect 클라우드(managed prefect cloud): 배포된 작업은 기본적으로 prefect 클라우드의 prefect 서버에 등록된다.
prefect server start
명령을 실행한다.일거리 풀(work pool): 플로우를 관리하고 실행하는 prefect 서버의 기능이다.
serve
메서드와 함수를 이용해 플로우를 쉽게 배포할 수 있었다. 하지만 (1) 동적인 환경 프로비저닝, (2) 작업 우선순위 큐 관리, (3) 협업 등 조금 더 복잡한 설정이 필요한 경우에는 일거리 풀이라는 중간 계층 레이어를 사용해야 한다. prefect work-pool create example-pool
명령으로 작업 풀을 만들고, 플로우의 deploy
메서드를 호출하여 일거리 풀에 플로우를 등록(assign)하는 방식으로 배포한다.prefect config set
명령을 이용해 PREFECT_API_URL
를 지정해야 일거리 풀 관련 명령들이 prefect 클라우드에 접근을 시도하면서 생기는 문제들을 방지할 수 있다. (https://github.com/PrefectHQ/prefect-docker/pull/96/commits/939fbdcadfbf57a0a5d5e9b602ea643bd3178983)prefect worker start --pool example-pool
명령으로 심부름꾼을 고용할 수 있다. 고용된 심부름꾼도 무한루프에 빠져 요청을 대기한다. (task를 ‘작업’으로 번역했으므로, 중복을 피하기 위해 work을 ‘일거리’, worker을 ‘심부름꾼’로 번역한다.)
일거리 풀과 심부름꾼의 역할을 그림으로 표현하면 다음과 같다.
prefect 일거리 풀의 종류는 다양하다. 어떤 일거리 풀에는 심부름꾼이 필요하지만, 어떤 일거리 풀에는 심부름꾼이 필요없다. 이때 심부름꾼이 필요한 일거리 풀을 심부름꾼 기반(worker based) 일거리 풀이라고 부른다.
도커 타입(docker type) 일거리 풀: 일거리 풀에 보내지는 모든 일거리들이 도커 컨테이너 환경에서 실행되는 일거리 풀을 의미한다. 도커 타입 일거리 풀은 심부름꾼 기반 일거리 풀이다.
--type docker
옵션을 추가하여 만들 수 있다.parse me : 언젠가 이 글에 쓰이면 좋을 것 같은 재료들.
Great source series
Unlocking MLOps using Airflow: A Comprehensive Guide to ML System Orchestration
from : 과거의 어떤 생각이 이 생각을 만들었는가?