Bigdata, DBT

Jeonghak Cho·2025년 4월 27일

Bigdata

목록 보기
21/30

📗DBT(data build tool) 개요

dbt란 데이터 변환(transform)을 SQL 기반으로 관리하는 도구이다. 데이터 엔지니어 → 데이터 모델러 → 비즈니스 분석가" 사이를 자연스럽게 이어주는 ELT 중심 도구이다.

dbt가 처음 등장한 이유는 다음과 같은 예전 데이터 파이프라인 문제점 때문이다.

  • 데이터 엔지니어가 ETL 코드를 Python, Java로 짬.
  • 코드가 복잡해서 분석가들은 수정 불가. (비개발자 장벽 높음)
  • 데이터 흐름이 스파게티처럼 엉켜버림.
  • SQL은 DB 안에서 따로 써야 해서 버전 관리도 안 됨.
  • 테이블 관계가 복잡해도 문서화는 수작업.결국 데이터 파이프라인이 코드 관리가 안 되고, 분석가랑 엔지니어가 따로 놀았다.

dbt가 해결한 것은 다음과 같다.

  • 분석가도 직접 데이터 파이프라인 고칠 수 있게 됨.
  • Git으로 코드처럼 버전 관리 가능.
  • 테이블간 의존관계를 자동으로 그래프로 그려줌.
  • 데이터 품질을 SQL로 직접 검증 가능.
  • 문서화가 자동화.데이터 파이프라인을 소프트웨어처럼 다룰 수 있게 만든 최초의 도구였다.

"ETL은 개발자가 만든다"는 전통적 사고방식은 버려야 한다. dbt를 쓰려면 조직이 "데이터 변환을 오픈하고 협업한다"는 마인드가 필요하다.

🏳️‍🌈 [궁금한점]

  • DBT를 왜 사용해야 하는가
  • Spark 사용에 연계할 수 있나
  • ICEBERG 와 함께 사용가능하나

🔗목차

DBT가 중요한 이유

이유설명
SQL만 알면 된다Python이나 Java 몰라도 된다.
버전 관리Git으로 파이프라인 버전 관리가 가능하다.
테스트 내장데이터 검증 로직이 쿼리 옆에 붙는다.
문서 자동화데이터베이스 구조를 자동으로 문서화해준다.
DAG 관리테이블 간의 의존성(DAG)을 코드로 선언적으로 관리한다.
DevOps 친화적CI/CD 파이프라인에 쉽게 연결된다.

DBT 사용 전후 비교

예전dbt 이후
데이터 엔지니어가 ETL 담당 → 분석가들은 못 건드림분석가, 엔지니어 모두 SQL로 협업
Python/Java 스크립트 복잡SQL 기반 간결한 모델링
수작업 문서화문서화 자동화, lineage도 자동
ETL 배포 어려움Git+CI/CD로 배포 자동화 가능
오류나면 디버깅 힘듦dbt test로 사전 검증

주요개념

개념설명
ModelSQL 파일 하나 = 하나의 테이블(또는 뷰). select 쿼리로 정의
DAG모델 간 의존 관계를 그래프로 그려준다. (upstream → downstream)
Test컬럼 값이 NULL이면 안 된다, unique해야 한다 같은 걸 자동 검증
Documentation모델 정의서, lineage(계보)를 자동 문서화해줌
SeedCSV 파일을 테이블처럼 로딩해서 쓸 수 있음
Snapshot테이블 변경 이력을 관리하는 기능 (타임 트래블처럼)
Run / Build정의한 모델을 실제로 실행해서 테이블/뷰로 만들어줌

DBT 사용의 필요성

팀이 커지고, 테이블 수가 많아지거나, 운영환경(dev/stg/prod)이 나뉘면 dbt 없이 버티기 힘들다. dbt는 규모가 커질 때 진가를 발휘한다. dbt는 작은 문제에는 과하지만, 큰 문제를 미리 예방하는 보험 같은 도구이다.

SQL만 쓸 때

foo.sql, bar.sql 이렇게 파일 여러 개 만들어 놓고 쿼리 작성해서 데이터베이스에 직접 CREATE TABLE AS SELECT 실행한다. 이 경우, 각 쿼리 간 의존성(순서)을 사람이 기억해야하고, 변경사항은 수작업 (ALTER TABLE 직접 실행)으로 진행된다. 문서화는 엑셀이나 위키 따로 정리해야 한다. 테스트는 사람 눈으로 직접 확인 (null 체크, unique 체크)한다.

이 경우 발행할 수 있는 문제점은 다음과 같다

  • 실행 순서를 잊어버리거나 틀릴 수 있음
  • 테이블 변경 이력 추적이 어려움 (버전 관리 안 됨)
  • 데이터 품질 이슈 생기면 디버깅 힘듦
  • 팀원이 늘어나면 코드 스타일이 틀려진다.

dbt를 쓸 때

models/ 안에 각 계층별로 폴더 구분 (raw/, staging/, mart/)한다. 모델 간 의존성을 ref() 함수로 명시한다. dbt run 하면 의존성 순서대로 자동 실행된다. 변경사항은 Git PR로 관리한다. 문서화는 dbt docs로 자동진행된다. 데이터 품질은 dbt test로 자동화한다. 코드 재사용은 macro로 템플릿화한다.

좋아지는 점은 다음과 같다.

  • 실행 순서가 자동 관리됨 (DAG처럼)
  • 모델마다 설명을 달 수 있어 (description 필드)
  • 컬럼 변경이나 추가가 PR로 투명하게 관리됨
  • 문서/테스트/실행이 모두 표준화됨
  • 데이터 문제 발생 시 추적이 쉬움

Spark에서 DBT 활용

DBT와 Spark 비교

항목dbtSpark
정체성데이터 변환(Transform) 자동화 도구분산 데이터 처리 엔진
핵심 기능SQL 기반 모델 작성, 실행, 관리, 테스트대규모 데이터 연산(ETL, 머신러닝, 스트리밍 처리)
주 언어SQL (Jinja 템플릿 사용 가능)Scala, Java, Python, SQL
동작 방식명령어로 SQL을 순차 실행 (ELT 중심)클러스터 기반 분산 컴퓨팅 (RDD, DataFrame)
처리 대상보통 "테이블 가공" (데이터 양은 작을 수도 있음)수 TB~PB급 데이터 처리 가능
리소스 관리없음 (백엔드에 의존)있음 (Executor, Driver 관리)
용도데이터 모델링, 파이프라인 오케스트레이션복잡한 변환, ML, 대규모 데이터 분석

dbt는 "어떤 변환을 할지" 정의하고, Spark는 "변환을 실제로 어떻게 처리할지" 실행한다. 둘을 연계해서 활용한다.
| 구성 | 설명 |
|--------------------|----------------------------------------------|
| dbt-spark adapter | dbt가 Spark를 통해 테이블 생성/변환 명령을 날림 |
| Spark backend | 실제로 클러스터가 데이터 가공 실행 |
| 결과 | dbt 프로젝트에서 만든 모델이 Spark에서 병렬로 빠르게 처리 |

DBT 없이 Spark만 쓸 때 생기는 문제

코드 관리 지옥

  • Spark SQL, DataFrame 코드가 여기저기 흩어짐
  • 파이프라인 복잡해지면 어느 쿼리가 먼저 실행돼야 하는지, 어떤 테이블이 어떤 테이블에 의존하는지, 이 버전이 맞는지
    , 전부 사람이 기억하거나, 문서로 관리해야 한다.

재사용성 없음

Spark에서는 SELECT * FROM 테이블 할 때 그냥 코드 복붙하거나 별도 스크립트 관리한다. 수정하려면 모든 스크립트 찾아다니면서 고쳐야 한다.

테스트/품질관리 힘듦

Spark만 쓰면 "테이블이 잘 만들어졌는지" 자동으로 검증하기 어렵다. 일일이 수작업으로 테스트하거나, 별도 스크립트 짜야 한다.

배포(Deployment)

Spark만 쓰면 버전 관리가 어렵다. 어떤 쿼리가 운영에 올라간 건지 추적 힘들다. rollback(롤백)도 수작업으로 진행해야 한다. 프로덕션/개발 환경 분리도 별도 커스텀 짜야 한다. 데이터팀이 커질수록 "배포 실수" 늘어난다.

DAG 관리 없음

파이프라인의 의존관계(DAG)가 명시적이지 않다. 어느 테이블이 어느 테이블을 참조하는지 파악하기 힘들다. 문제 생기면 어디가 원인인지 찾기 힘들어서 장애 대응 시간 늘어난다.

Spark만dbt + Spark
쿼리 흩어짐SQL 모델 관리, 디렉토리 구조
수동 의존성 관리DAG 자동 생성
수동 테스트자동 test 관리 (dbt test)
수동 배포버전 관리 + 배포 (dbt run)
수작업 품질검사데이터 품질 체크 자동화

개발 도구인 MyBatis와 비교

도구가 처리하는 목적이나 실행 시점, 사용되는 언어가 매우 다르다
| 항목 | MyBatis | DBT |
|----------------|------------------------------------------|--------------------------------------|
| 주요 목적 | 애플리케이션 코드에서 DB 조회/변경하기 (ORM/SQL Mapper) | 데이터 웨어하우스에서 데이터 변환(Transform)하고 관리하기 |
| 사용하는 곳 | 백엔드 서버 (Java/Spring 등) | 데이터 엔지니어링, 데이터 플랫폼 |
| 다루는 SQL | 단일 트랜잭션(SQL) → Insert/Select/Update/Delete | 대량 변환(SQL) → Create Table as Select (CTAS), View 생성 |
| 주요 대상 | 트랜잭션성 데이터 (고객, 주문 데이터 CRUD) | 분석용 데이터 (DW, DM, Data Lake) |
| 실행 시점 | 사용자 요청시 (API 호출 등) | 스케줄러가 주기적으로 실행 (ETL 파이프라인) |
| 버전 관리 | 코드에 같이 묶여 관리 (Java 소스랑 함께) | 별도 Git 저장소에 SQL만 관리 |
| 주 사용 언어 | Java + XML(SQL) | SQL + Jinja (템플릿) |

dbt Iceberg 조합

dbt는 기본적으로 쿼리를 실행해서 테이블/뷰를 만든다. Iceberg는 쿼리로 조작 가능한 테이블 포맷이다 (ex. Trino, Spark, Flink, Snowflake 등에서 읽기/쓰기 가능). 즉, dbt가 Iceberg 테이블을 대상으로 모델링/변환 작업하는 게 가능하다.

구성설명
dbt → TrinoTrino가 Iceberg를 읽고 쓸 수 있으니까, Trino adapter로 dbt 연결
dbt → SparkSpark SQL로 Iceberg 테이블 조작 가능, Spark adapter 사용
dbt → Snowflake요즘은 Snowflake도 Iceberg 테이블 외부로 연결 가능해서 이걸 통해 사용 가능
  • 예시 모델 (models/orders_summary.sql)
{{ config(
    materialized='table',
    schema='iceberg',
    database='lakehouse'
) }}

SELECT
  customer_id,
  COUNT(*) AS total_orders,
  SUM(amount) AS total_amount
FROM {{ source('iceberg', 'orders') }}
GROUP BY customer_id

dbt run 하면, Iceberg에 새로운 테이블이 생성된다.

Iceberg 테이블 관리할 때 dbt를 쓰는 장점

항목설명
SQL 하나로Iceberg 테이블 생성/변경 모두 SQL로 가능
Schema Evolution컬럼 추가/삭제도 dbt 모델에서 관리 가능
Version 관리dbt가 Git 기반이라 모델 버전 히스토리 관리 가능
DAG 자동 생성Iceberg 테이블 가공하는 흐름도 자동으로 시각화

0개의 댓글