프로젝트 파싱
프로젝트 파싱 (Project Parsing)
모든 dbt 실행의 시작에서 dbt가 프로젝트의 모든 파일을 읽고 정보를 추출해 매니페스트를 만드는 과정이에요. 파싱 성능을 높이는 여러 최적화 기법이 있어요.
출처: 문서
본문
관련 문서 (Related documentation)
dbt parse명령- Partial parsing 프로필 설정과 CLI 플래그
- Parsing CLI 플래그
파싱이란 무엇인가요? (What is parsing?)
모든 dbt 실행의 시작에서 dbt는 프로젝트의 모든 파일을 읽고 정보를 추출한 뒤, 모든 객체(모델, 소스, 매크로 등)를 담은 매니페스트(manifest)를 구성해요. 무엇보다도 dbt는 모델 내부의 ref(), source(), config() 매크로 호출을 사용해 속성을 설정하고, 의존성을 추론하며, 프로젝트의 DAG를 구성해요.
프로젝트 파싱은 느릴 수 있어요. 특히 프로젝트가 커질수록(수백 개 모델, 수천 개 파일) 개발이 답답해져요. 현재 dbt 성능을 최적화하는 방법은 몇 가지가 있어요:
- PyYAML용 LibYAML 바인딩
- Partial parsing — 실행 사이에 변경되지 않은 파일의 재파싱을 피함
- Static parser — 단순한 모델에서 정보를 훨씬 빨리 추출함
- RPC server — 매니페스트를 메모리에 유지하고 서버 시작/종료 시 프로젝트를 재파싱함
이 최적화들은 조합해서 파싱 시간을 분 단위에서 초 단위로 줄일 수 있어요. 동시에 각각 알려진 제한사항이 있기 때문에 기본적으로는 비활성화되어 있어요.
PyYAML + LibYAML
dbt는 PyYAML을 사용해 프로젝트의 YAML 파일을 읽고 검증해요. PyYAML은 순수 Python으로 작성됐지만, 시스템에 LibYAML(C로 작성돼 훨씬 빠름)이 있다면 이를 활용할 수 있어요. dbt는 프로젝트를 파싱할 때마다 항상 LibYAML이 있는지 먼저 확인해요.
LibYAML이 설치됐는지 확인하려면 dbt를 설치한 환경에서 다음 명령을 실행하세요:
python -c "from yaml import CLoader"
Partial parsing
프로젝트를 파싱한 뒤 dbt는 내부 프로젝트 매니페스트를 partial_parse.msgpack이라는 파일에 저장해요. Partial parsing이 활성화되면 dbt는 그 내부 매니페스트를 사용해 마지막으로 프로젝트를 파싱한 이후 어떤 파일이 변경됐는지(있다면) 결정해요. 그런 다음 변경된 파일만, 또는 그 변경과 관련된 파일만 파싱해요.
v1.0부터 partial parsing은 기본적으로 켜져 있어요. 개발에서는 partial parsing이 실행 시작 시 대기 시간을 크게 줄여줘서 더 빠른 개발 사이클과 반복을 가능하게 해요.
PARTIAL_PARSE 전역 설정은 profiles.yml, 환경 변수, CLI 플래그를 통해 활성화/비활성화할 수 있어요.
(dbt v2.0 이상에 적용)
dbt v2와 partial parsing — dbt v2 작업 실행은 더 이상 --partial-parse와 --no-partial-parse CLI 플래그를 지원하지 않아요. 이를 전달하면(예: dbt v1 명령이나 스크립트에서) dbt는 deprecation 경고 dbt1700을 로깅해요. dbt v2 작업 명령에서 이 플래그들을 제거하세요. 자세한 내용은 dbt v2 업그레이드 가이드의 Deprecated flags를 참고하세요.
알려진 제한 사항 (Known limitations)
파싱 시간 속성(의존성, 설정, 리소스 속성)은 parse-time 컨텍스트를 사용해 해석돼요. Partial parsing이 활성화되고 특정 컨텍스트 변수가 변경되면 해당 속성은 다시 해석되지 않아 오래된 상태(stale)가 되기 쉽습니다.
특히 run_started_at, invocation_id, flags 같은 "휘발성" 컨텍스트 변수에 이러한 속성이 의존하면 잘못된 결과가 나올 수 있어요. 이 변수들은 매 실행마다 변할 가능성이 높고(사실상 보장됨) 요. dbt Labs는 이런 변수로 parse-time 속성(의존성, 설정, 리소스 속성)을 설정하는 것을 강력히 권장하지 않아요.
v1.0부터 dbt는 환경 변수의 변경을 감지해 그 env_var 값에 의존하는 파일만 선택적으로 재파싱해요. (profiles.yml이나 dbt_project.yml에서 env var를 사용하면 전체 재파싱이 필요해요.) 다만 dbt는 env var를 포함한 설명(descriptions)을 다시 렌더링하지 않아요. 자주 바뀌는 env var가 설명에 포함됐다면(매우 드묾), 문서 생성 시 전체 재파싱 dbt docs generate --no-partial-parse를 권장해요.
실행 사이에 특정 입력이 변경되면 dbt는 전체 재파싱을 트리거해요. 결과는 정확하지만 전체 재파싱은 꽤 느릴 수 있어요. 현재 그 입력들은:
--varsprofiles.yml내용(또는 그 안에서 사용된 env_var 값)dbt_project.yml내용(또는 그 안에서 사용된 env_var 값)- 설치된 패키지
- dbt 버전
- 특정 널리 사용되는 매크로(예:
builtins, overrides, 또는 database/schema/alias용generate_x_name)
CI 작업 실행을 트리거한다면, partial parsing의 이점은 새로운 PR이나 새 브랜치에는 적용되지 않아요. 다만 새 PR·브랜치의 이후 커밋에는 적용돼요.
Partial parsing이 활성화되면 dbt가 가끔 실패하거나 프로젝트를 잘못 파싱해 다음을 일으킬 수 있어요:
- 노드(예: 모델, 소스)가 발견되지 않음.
- 설정이 잘못 설정됨(예: 모델의 schema.yml 파일에 정의된 것과 다르게).
이런 상태가 되면 다음 옵션 중 하나로 전체 재파싱을 트리거할 수 있어요:
--no-partial-parse로 dbt 명령 실행.dbt clean으로target/partial_parse.msgpack파일 삭제.
PARTIAL_PARSE 전역 설정을 false로 설정하면 partial parsing을 완전히 비활성화할 수도 있어요.
Static parser
파싱 시 dbt는 프로젝트의 모든 모델에서 ref(), source(), config()의 내용을 추출해야 해요. 전통적으로 dbt는 모든 모델 파일의 Jinja를 렌더링해 그 값을 추출했는데, 이는 느릴 수 있어요. 이제는 tree-sitter를 활용해 모델 파일을 정적으로 분석해요. 초기 Jinja2 문법 코드를 볼 수 있어요.
Static parser는 기본적으로 켜져 있어요. 최대 95%의 프로젝트에서 속도 향상을 제공할 수 있다고 봐요. STATIC_PARSER 전역 설정으로 선택적으로 끌 수 있어요.
현재 static parser는 모델에서만, 그리고 Jinja가 그 세 가지 특수 매크로(ref, source, config)로만 제한된 모델에서만 동작해요. static parser는 전체 Jinja 렌더링보다 최소 3배 빠릅니다. dbt 데이터를 기반으로 한 테스트에 따르면 현재 문법은 실제 모델의 60%를 정적으로 파싱할 수 있어요. 그래서 평균적인 프로젝트에서는 모델 파서에서 약 40%의 속도 향상을 기대할 수 있어요.
더 알아보기 (Learn more)
dbt parse명령과 partial parsing · static parser 관련 CLI 플래그는 dbt Commands 문서를 참고하세요.- 전역 설정(
PARTIAL_PARSE,STATIC_PARSER)은 Global configs 문서를 참고하세요.