← 학습 카테고리

Learn

dbt

11개 모듈 · 현재 11번째

dbt 모듈 11/11 dbt-learn-11

환경 격리·Deferral·시크릿 관리와 프로젝트 구조화

50 dbt Interview Questions for Data Engineers (Real Answers, 2026) — 미상 (데이터 엔지니어링 커리어 블로그, 2026) Section 5: Production & Deployment, Q44-Q50 및 FAQ 'How do you debug a failing dbt model?' (pp.14-18)

이 모듈을 다 읽으면

  • 환경(dev/ci/prod)이 스키마 수준에서 어떻게 격리되는지, target.name으로 환경별 로직을 어떻게 다루는지 설명할 수 있다
  • deferral이 무엇이고 dbt Core에서도 쓸 수 있다는 점, 시크릿 관리 원칙을 설명할 수 있다
  • seeds 사용 기준, 프로덕션 모니터링 항목, 3계층(staging/intermediate/marts) 프로젝트 구조를 판단할 수 있다

dbt 환경은 target(연결 정보, 스키마, 웨어하우스)과 dbt 버전의 조합이며 dev/ci/prod가 스키마 단위로 격리된다. deferral(--defer --state)은 dbt Core에서도 쓸 수 있는 기능으로 재빌드가 필요 없는 모델은 프로덕션 버전을 참조하게 해 개발 속도를 높인다. 자격증명은 env_var()로만 주입하고, seeds는 작고 자주 바뀌지 않는 룩업 데이터 전용이며, 프로덕션 모니터링은 run_results.json 기반 실행 시간·테스트 통과율·프레시니스를 추적한다. 프로젝트는 staging/intermediate/marts 3계층 구조와 stg_/int_/fct_/dim_ 네이밍 컨벤션으로 조직해야 팀이 커져도 유지보수가 가능하다.

환경 격리, target.name, Deferral, 시크릿

환경은 target(연결 정보, 스키마, 웨어하우스)과 dbt 버전의 조합이다. 최소한 dev(개발자별 개인 스키마), ci(PR마다 생성되는 임시 스키마), prod(프로덕션 스키마)가 필요하다. 격리는 스키마 수준에서 일어난다 — 개발자 A는 dev_alice에, 개발자 B는 dev_bob에 쓰고 누구도 prod를 건드리지 않는다. dbt Cloud는 이를 네이티브로 관리하고, Core에서는 profiles.yml에서 구성한다.

환경별 로직은 Jinja의 target.name으로 다룬다: {% if target.name == 'prod' %}로 설정·필터·샘플링을 조건부로 적용한다. 실용적인 예로, dev에서는 빠른 반복을 위해 대형 테이블을 100만 행으로 제한할 수 있다({% if target.name == 'dev' %} LIMIT 1000000 {% endif %}). 다만 모델 안에 분기 로직을 과도하게 넣는 것은 피해야 한다 — dev와 prod의 코드 경로가 크게 갈라지면 dev 테스트가 실제 프로덕션에서 실행되는 것을 검증하지 못하게 된다.

deferral은 재빌드가 필요 없는 모델에 대해 dev나 CI 실행이 프로덕션 테이블을 참조하도록 해준다. model_C를 바꿨고 그것이 model_A, model_B에 의존한다면, dbt는 A와 B를 먼저 빌드하라고 요구하는 대신 그 프로덕션 버전을 쓴다. 이는 대형 프로젝트에서 개발 실행 시간을 극적으로 줄인다. --defer --state ./prod-artifacts/로 활성화한다.

— 정정: 원문은 이 절의 제목을 'dbt Cloud에서의 deferral'이라고 붙여 마치 dbt Cloud 전용 기능처럼 서술하지만, 이는 정확하지 않다. --defer와 --state 플래그는 dbt-core CLI 자체의 기능이며(과거 dbt-core 0.18/0.19 즈음부터 제공), dbt Cloud 없이도 로컬이나 CI에서 그대로 쓸 수 있다. dbt Cloud가 제공하는 것은 이 기능을 감싼 편리한 UI와 '변경 사항 비교(compare changes)' 같은 잡 통합일 뿐, deferral 자체의 동작 원리는 Core와 Cloud가 동일하다.

자격증명은 profiles.yml이나 dbt_project.yml에 절대 하드코딩하지 않는다. Core에서는 환경 변수를 쓴다: password: "{{ env_var('DBT_PASSWORD') }}". CI/CD에서는 GitHub Secrets나 볼트 시스템에 시크릿을 저장하고 환경 변수로 주입한다. dbt Cloud는 UI의 환경 변수를 통해 시크릿 관리를 내장 제공한다. 가장 흔한 감사 지적 사항은 profiles.yml에 자격증명이 Git에 커밋된 것이므로, 항상 .gitignore에 추가해야 한다.

핵심 포인트

  • 환경(target)은 스키마 단위로 격리되며(dev_alice, dev_bob, prod 등), dbt Cloud는 네이티브로, Core는 profiles.yml로 관리한다
  • target.name으로 환경별 조건부 로직을 넣되, dev/prod 코드 경로가 크게 갈라지면 dev 테스트의 신뢰성이 떨어진다
  • deferral(--defer --state)은 재빌드가 불필요한 모델을 프로덕션 버전으로 대체해 개발 속도를 높인다
  • deferral은 dbt Cloud 전용이 아니라 dbt-core CLI 자체의 기능이며, dbt Cloud는 이를 감싼 UI만 얹은 것이다 — 정정
  • 자격증명은 반드시 env_var()로 주입하고 profiles.yml은 .gitignore 처리해야 한다

Seeds, 프로덕션 모니터링, 프로젝트 구조, 디버깅

seeds는 dbt seed로 웨어하우스에 테이블로 적재되는, seeds/ 디렉터리 안의 CSV 파일이다. 국가 코드, 상태 매핑, 부서 목록 같은 작고 정적인 룩업 데이터에 쓴다. 수천 행을 넘거나 자주 바뀌는 데이터에는 쓰지 말아야 한다 — 그런 데이터는 EL 파이프라인이 담당할 몫이다. 흔한 안티패턴은 CI 테스트 픽스처로 seeds를 쓰는 것인데, 동작은 하지만 seed 개수가 늘어날수록 느려진다.

프로덕션에서 dbt 프로젝트를 모니터링하려면 최소한 모델 실행 시간(run_results.json 기준), 테스트 통과/실패율, 소스 프레시니스를 추적해야 한다. dbt Cloud는 이를 위한 대시보드를 제공한다. Core에서는 매 실행 후 run_results.json을 파싱해 Datadog, Grafana 같은 모니터링 스택으로 메트릭을 보낸다. 실행 시간이 2배 이상 증가하는 모델에 알림을 설정하면 좋다 — 대체로 상류 데이터 볼륨 급증이나 파티션 필터 누락을 의미하기 때문이다.

성장하는 팀을 위한 표준 프로젝트 구조는 3계층이다: staging(원천 테이블당 모델 하나, 가벼운 이름 변경·캐스팅, 항상 view), intermediate(아직 최종이 아닌 비즈니스 로직 조인·집계), marts(BI 도구가 소비하는 최종 와이드 테이블). 네이밍 컨벤션을 강제한다: stg_, int_, fct_, dim_. 각 원천 시스템은 자신의 staging 서브폴더에 둔다. CODEOWNERS로 폴더별 리뷰 책임을 지정한다. 이 구조는 모델 10개에서 1,000개로 커져도 무너지지 않는다.

실패한 dbt 모델을 디버깅할 때는 dbt run --select <model_name>으로 범위를 좁힌다. 컴파일은 되는데 결과가 이상하다면 target/compiled/.../<model>.sql에서 dbt가 실제로 생성한 SQL을 확인하고, 그 SQL을 웨어하우스에서 직접 실행해 디버깅한다. 의존성 문제라면 dbt list --select +<model> --resource-type model로 DAG 상류를 점검한다. 데이터 문제라면 dbt show --select <model>로 출력을 미리 본다.

핵심 포인트

  • seeds는 작고 정적인 룩업 데이터(CSV)에만 쓰고, 대용량·자주 바뀌는 데이터는 EL 파이프라인에 맡긴다
  • 프로덕션 모니터링은 run_results.json 기반 실행 시간, 테스트 통과율, 소스 프레시니스가 최소 항목이며 실행 시간 2배 증가에 알림을 걸어둔다
  • 표준 프로젝트 구조: staging(원천 1:1, view)-intermediate(중간 로직)-marts(최종 소비 테이블), stg_/int_/fct_/dim_ 네이밍
  • 디버깅 순서: dbt run --select로 범위 좁히기 -> target/compiled/의 컴파일된 SQL 직접 실행 -> dbt list --select +<model>로 DAG 점검 -> dbt show로 출력 미리보기