개요
Prefect는 탄력적인 데이터 파이프라인을 구축하기 위한 Python 워크플로 오케스트레이션 프레임워크입니다. 데코레이터를 통해 스크립트를 프로덕션급 워크플로로 변환하며, 스케줄링, 캐싱, 재시도 및 이벤트 기반 자동화를 지원합니다. 자체 호스팅 서버 또는 관리형 클라우드 대시보드를 통해 워크플로 활동을 모니터링할 수 있습니다.
README 미리보기
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n\n\n\n \n Installation\n \n ·\n \n Quickstart\n \n ·\n \n Build workflows\n \n ·\n \n Deploy workflows\n \n ·\n \n Prefect Cloud\n \n\n\n# Prefect\n\nPrefect is a workflow orchestration framework for building data pipelines in Python.\nIt's the simplest way to elevate a script into a production workflow.\nWith Prefect, you can build resilient, dynamic data pipelines that react to the world around them and recover from unexpected changes.\n\nWith just a few lines of code, data teams can confidently automate any data process with features such as scheduling, caching, retries, and event-based automations.\n\nWorkflow activity is tracked and can be monitored with a self-hosted [Prefect server](https://docs.prefect.io/latest/manage/self-host/?utm_source=oss&utm_medium=oss&utm_campaign=oss_gh_repo&utm_term=none&utm_content=none) instance or managed [Prefect Cloud](https://www.prefect.io/cloud-vs-oss?utm_source=oss&utm_medium=oss&utm_campaign=oss_gh_repo&utm_term=none&utm_content=none) dashboard.\n\n> [!TIP]\n> Prefect flows can handle retries, dependencies, and even complex branching logic\n> \n> [Check our docs](https://docs.prefect.io/v3/get-started/index?utm_source=oss&utm_medium=oss&utm_campaign=oss_gh_repo&utm_term=none&utm_content=none) or see the example below to learn more!\n\n## Getting started\n\nPrefect requires Python 3.10+. To [install the latest version of Prefect](https://docs.prefect.io/v3/get-started/install), run one of the following commands:\n\n```bash\npip install -U prefect\n```\n\n```bash\nuv add prefect\n```\n\nThen create and run a Python file that uses Prefect `flow` and `task` decorators to orchestrate and observe your workflow - in this case, a simple script that fetches the number of GitHub stars from a repository:\n\n```pyt
FAQ (5)
문제 해결Prefect 스키마 유효성 검사에서 중첩된 속성 순서에 따라 None이 통과되거나 "None is not of type 'string'" 오류로 실패하는 문제를 어떻게 해결해야 하나요?
이 문제는 prefect.utilities.schema_tools.validation.process_properties()의 버그로 인해 발생합니다(Prefect 3.8.7.dev6, main 커밋 148e9978에서 재현됨). 루프가 required_fields를 중첩 객체의 required 목록으로 다시 바인딩하므로, 이후 형제 속성들이 잘못된 목록을 기준으로 검증됩니다. 재귀 호출 또한 allow_none_with_default를 전달하지 못합니다.
issue #23189에 대한 수정 사항이 포함된 Prefect 릴리스로 업그레이드하십시오. main에서 개발용으로 설치하려면:
python -m pip install --upgrade "prefect @ git+https://github.com/PrefectHQ/prefect.git"
소스를 직접 패치하는 경우, required_fields를 재할당하는 대신 중첩된 필수 필드에 별도의 변수를 사용하십시오:
if "properties" in schema: nested_required = schema.get("required", []) process_properties( schema["properties"], nested_required, allow_none_with_default=allow_none_with_default, )
속성 루프 내에서 required_fields = schema.get("required", [])를 사용하지 마십시오.
임시 해결 방법: 각 스키마 수준에서 중첩 객체 속성을 모든 형제 속성 뒤에 배치하고, 기본값이 있는 중첩 필드에서는 allow_none_with_default에 의존하지 마십시오. 명시적인 기본값을 전송하거나, None이 실제로 허용되는 경우에만 "type": ["string", "null"]로 필드를 nullable로 선언하십시오.
문제 해결Prefect Cloud 점검 중에 Prefect runner liveness probe가 serve 중인 flow를 재시작하지 않도록 하려면 어떻게 해야 하나요?
이 문제는 Prefect 3.8.8에 영향을 미칩니다. Cloud 유지 관리 중에는 API 호출이 Prefect-Maintenance: true 및 Retry-After와 함께 503을 반환하므로, 러너가 폴링을 백오프합니다. 그러면 /health 엔드포인트가 PREFECT_RUNNER_SERVER_MISSED_POLLS_TOLERANCE × PREFECT_RUNNER_POLL_FREQUENCY(기본값 2 × 10 = 20초) 이후에 503을 반환하고, 첫 번째 폴링이 완료되기 전에 500을 반환할 수 있어, liveness probe가 러너를 재시작하게 만듭니다.
**영구 해결 방법:** issue #23326에 대한 러너 유지 관리 헬스체크 수정이 포함된 릴리스로 Prefect를 업그레이드하세요:
pip install -U prefect
패치된 버전에서는 클라이언트가 유지 관리 백오프를 따르는 동안 /health가 정상 상태를 유지하며, 첫 번째 성공적인 폴링이 이루어지기 전에 더 이상 오류를 반환하지 않습니다.
**영향을 받는 버전에서의 해결 방법:** 폴링 누락 임계값을 예상되는 유지 관리 기간보다 길게 설정하세요:
export PREFECT_RUNNER_POLL_FREQUENCY=10
export PREFECT_RUNNER_SERVER_MISSED_POLLS_TOLERANCE=60
이렇게 하면 /health가 비정상으로 보고되기까지 600초(60 × 10)가 허용됩니다.
Kubernetes에서는 probe도 동일한 기간을 허용하도록 설정하고, 유지 관리 중에 시작되는 프로세스에는 startup probe를 사용하세요:
livenessProbe:
httpGet:
path: /health
port: 8080
periodSeconds: 10
failureThreshold: 60
timeoutSeconds: 5
startupProbe:
httpGet:
path: /health
port: 8080
periodSeconds: 10
failureThreshold: 60
startup probe는 flow.serve()/serve()가 러너 웹서버가 시작되기 전에 deployment를 등록하기 때문에 중요합니다. 따라서 시작 과정이 유지 관리를 기다리는 동안 /health가 연결을 거부할 수 있습니다.
문제 해결Windows에서 `prefect deploy`를 실행할 때 flow picker에 백슬래시 경로가 표시되는 이유는 무엇인가요?
flow picker는 str(path)를 사용하여 pathlib.Path를 문자열로 변환하는데, 이는 Windows 고유의 백슬래시를 사용합니다. Entrypoint는 flows/hello.py:my_flow와 같이 POSIX 스타일의 포워드 슬래시를 사용해야 합니다.
prefect/_internal/ast_utils.py의 find_prefect_decorated_functions_in_file 내부에서 다음을:
"filepath": str(path)
다음과 같이 교체하여 수정하세요:
"filepath": path.as_posix()
포워드 슬래시 경로는 Windows에서도 올바르게 작동하며, 예상되는 path/to/file.py:function_name entrypoint 형식을 생성합니다.
임시 해결 방법:
1. 수동 entrypoint 옵션을 선택하고 포워드 슬래시를 사용하여 경로를 입력하세요: path/to/file.py:function_name.
2. 백슬래시가 prefect.yaml에 저장된 경우, 수동으로 포워드 슬래시로 교체하세요.
3. POSIX 경로 수정이 포함된 릴리스로 Prefect를 업그레이드하세요.
문제 해결Prefect Cloud 유지 관리(maintenance) 중에 Prefect worker의 liveness probe로 인해 worker가 재시작되는 것을 방지하려면 어떻게 해야 하나요?
Prefect 3.8.7에서는 Cloud 유지 관리 응답(Prefect-Maintenance: true 및 Retry-After를 포함한 503)이 워커 폴링을 차단합니다. 약 300초(PREFECT_WORKER_QUERY_SECONDS × 30) 후에는 /health가 503을 반환하여 Kubernetes가 워커를 재시작하게 됩니다. 재시작 후에도 setup()이 완료될 때까지 헬스 포트를 사용할 수 없어 probe 실패가 반복적으로 발생합니다.
공식 prefect-worker Helm chart를 사용한 즉각적인 해결 방법: 알려진 유지 관리 기간 동안 liveness probe를 비활성화합니다:
livenessProbe:
enabled: false
다음 명령으로 적용합니다:
helm upgrade worker prefect/prefect-worker -f values.yaml
또는:
helm upgrade worker prefect/prefect-worker --set livenessProbe.enabled=false
유지 관리 기간이 끝난 후에는 probe를 다시 활성화하십시오. 워커가 어떤 고정된 임계값보다 오래 유지 관리 백오프(back-off) 상태를 유지할 수 있으므로, probe 임계값이나 폴링 간격을 늘리는 것은 신뢰할 수 있는 방법이 아닙니다.
영구적인 해결 방법: 워커용 PR #23230이 포함된 Prefect 릴리스로 업그레이드하십시오. 해당 수정 사항은 헬스 상태를 평가할 때 유지 관리 백오프 종료 시간을 추적하고 setup() 이전에 헬스 서버를 시작하므로, 유지 관리 중에도 /health를 계속 사용할 수 있습니다. Runner 또는 flow.serve()를 사용하는 배포에는 별도의 runner 헬스체크 후속 수정도 필요합니다.
문제 해결--limit 사용 시 Prefect worker 크래시 "this borrower is already holding one of this CapacityLimiter's tokens"을(를) 해결하는 방법?
이 문제는 3.8.7 및 3.8.8과 같은 버전의 Prefect worker에 영향을 미칩니다. 폴링이 worker가 이미 실행 중인 flow run을 반환할 수 있습니다. submission ID는 인프라가 시작된 후 지워지지만, CapacityLimiter 토큰은 실행이 종료될 때까지 계속 보유된 상태로 유지됩니다. worker는 anyio.WouldBlock만 처리하므로, 중복 토큰으로 인한 RuntimeError가 폴링 루프를 종료시킵니다.
권장 해결 방법: issue #23340의 수정 사항이 포함된 패치된 Prefect 릴리스로 업그레이드한 후 worker를 재시작하십시오:
python -m pip install -U prefect
prefect version
패치된 버전에서는 중복 제출이 worker를 중단시키는 대신 로그에 기록되고 건너뜁니다.
업그레이드할 수 없는 경우 즉시 적용할 수 있는 해결 방법:
1. 충돌한 worker를 재시작하여 폴링을 재개합니다.
2. worker 명령에서 --limit을 제거합니다. 이렇게 하면 limiter를 우회할 수 있지만 로컬 동시성 상한도 함께 제거됩니다.
3. 소스 패치로는 prefect/workers/base.py의 _submit_scheduled_flow_runs에서 limiter acquire를 래핑하여 중복 토큰을 건너뛰도록 합니다:
try:
self._limiter.acquire_on_behalf_of_nowait(flow_run.id)
except RuntimeError as exc:
if "already holding one of this CapacityLimiter's tokens" in str(exc):
logger.info(
"Duplicate submission of flow run %s detected; skipping",
flow_run.id,
)
continue
raise
except anyio.WouldBlock:
# Keep the existing WouldBlock handling here
...
패치를 적용한 후 worker를 재시작하십시오.