lag_tolerance
lag_tolerance (지연 허용치)
lag_tolerance는 마지막 업스트림 데이터 변경 이후 dbt가 rebuild를 트리거하기까지 얼마나 시간이 지나야 하는지를 정하는 설정이에요. 데이터 신선도 SLA(서비스 수준 계약)에 맞춰 불필요한 rebuild를 줄이면서 컴퓨팅 비용을 아낄 수 있는 버퍼 역할을 해요.
출처: dbt 공식 문서
본문
설정 방법
프로젝트 YAML 파일
dbt_project.yml
models:
<resource-path>:
+state:
lag_tolerance: <duration_string>
프로퍼티 YAML 파일
models/
models:
- name: my_model
config:
state:
lag_tolerance: <duration_string>
SQL 파일 설정
models/
{{ config(
state={
"lag_tolerance": "<duration_string>"
}
) }}
정의
소스 시스템은 다운스트림 모델이 다시 빌드할 필요가 있을 때보다 더 자주 업데이트될 수 있어요. 예를 들어 일일 리포팅에 쓰는 모델은 업스트림 데이터가 매시간 새로 들어와도 하루에 한 번 이상 새로 고칠 필요가 없을 거예요.
lag_tolerance는 마지막 업스트림 데이터 변경 이후 dbt가 rebuild를 트리거하기까지 얼마나 시간이 지나야 하는지를 정해줘요. 이는 불필요한 rebuild 없이 데이터 신선도 서비스 수준 계약(SLA)에 맞춰 정렬하게 해주는 컴퓨팅 절약 버퍼 역할을 해요. 두 가지 핵심 시나리오를 지원해요.
- SLA 요구 사항에 맞춰 빌드 정렬하기:
lag_tolerance로 모델 실행을 데이터 신선도 SLA 요구 사항에 직접 맞출 수 있어요. 빈번한 업스트림 변경과, 더 넓고 덜 엄격한 신선도 요구 아래 동작하는 다운스트림 모델을 분리해줘요. - 업스트림 SLA 위반 시 컴퓨팅 보호:
lag_tolerance는 신선도 SLA 위반 동안 컴퓨팅 예산을 보호해줘요. 업스트림 의존성이 신선도 SLA를 위반할 때 정적 데이터에 대한 값비싼 다운스트림 rebuild를 막아줘요.
dbt State가 노드를 rebuild할지 평가할 때, 업스트림 부모에 lag_tolerance 임계값을 초과하는 신선한 데이터가 있는지 확인해요. 없으면 dbt는 기존 노드를 clone하거나 rebuild하는 대신 재사용해요.
이 설정은 두 가지 값 유형을 받아요.
-
기간 문자열
<숫자><단위>형식:단위 허용 값 초 s,second,seconds분 m,minute,minutes시간 h,hour,hours일 d,day,days주 w,week,weeks -
Jinja 표현식 -
lag_tolerance는 Jinja 템플릿으로 평가되므로, dbt 컨텍스트 변수(target,var(),env_var())를 사용해 동적으로 허용치를 정할 수 있어요. 환경마다 다른 허용치를 config 블록을 중복하지 않고 적용할 때 유용해요.lag_tolerance: "{{ '4h' if target.name == 'prod' else '7d' }}"
lag_tolerance는 언제 적용되나요?
lag_tolerance는 데이터 신선도 확인에만 적용돼요. 업스트림 모델의 컴파일된 SQL이 마지막 실행 이후 변경됐다면, 다운스트림 모델은 lag_tolerance 설정과 무관하게 허용치 창 안에서 여전히 rebuild돼요.
이런 일은 incremental 모델에서 자주 생겨요. incremental 모델이 처음 실행될 때는 WHERE 절 없는 전체 로드(full load)를 실행해요. 이후 실행에서는 is_incremental()이 true가 되어 필터가 추가되면서 컴파일된 SQL이 바뀌어요. dbt State는 이를 업스트림 모델의 쿼리 변경으로 감지하고, lag_tolerance가 아직 지나지 않은 모델을 포함해 모든 다운스트림 모델을 rebuild해요.
예를 들어 fct_orders는 agg_orders_daily가 의존하는 incremental 모델이에요.
models/fct_orders.sql
{{ config(materialized='incremental', unique_key='id') }}
select id, amount from {{ ref('raw_orders') }}
{% if is_incremental() %}
where id > (select max(id) from {{ this }})
{% endif %}
models/agg_orders_daily.sql
{{ config(materialized='table', state={'lag_tolerance': '3h'}) }}
select date_trunc('day', created_at) as day, sum(amount) as total
from {{ ref('fct_orders') }}
group by 1
fct_orders가 전체 로드에서 incremental 실행으로 전환되면 컴파일된 SQL이 바뀌어요. 그래서 agg_orders_daily는 3시간 lag_tolerance에도 불구하고 그 실행에서 rebuild돼요.
팁
lag_tolerance 값을 튜닝하는 데 도움을 주기 위해, dbt 플랫폼의 dbt State 페이지는 모델의 30일 빌드 이력을 바탕으로 lag tolerance 권장 사항을 제공해요. 어떤 모델이 더 높은 허용치를 쓰면 이득을 보는지 확인할 수 있어요.
기본값
45m이에요. lag_tolerance를 설정하지 않으면 dbt State는 기본 허용치 45분을 적용해요.
예시
환경마다 다른 허용치 사용하기
Jinja 표현식으로 프로덕션에서는 촘촘한 허용치를, 그 외 환경에서는 느슨한 허용치를 설정해요. 프로덕션 데이터를 신선하게 유지하면서 개발 중 불필요한 rebuild를 줄여줘요.
dbt_project.yml
models:
+state:
lag_tolerance: "{{ '4h' if target.name == 'prod' else '7d' }}"
이 예시에서 prod target의 모델은 업스트림 데이터가 4시간보다 오래됐을 때만 rebuild돼요. 그 외 모든 환경에서는 7일을 기다린 후 rebuild해요.
폴더마다 다른 허용치 적용하기
폴더를 대상으로 해 프로젝트의 다른 부분에 다른 허용치를 설정할 수 있어요.
dbt_project.yml
models:
<your_project>:
marts:
+state:
lag_tolerance: 1d
staging:
+state:
lag_tolerance: 1h
특정 모델에만 덮어쓰기
단일 모델에 대해 프로젝트 수준 기본값을 덮어써요.
models/my_model.yml
models:
- name: my_model
config:
state:
lag_tolerance: 1h