Перейти к основному содержимому

lag_tolerance

dbt_project.yml
models:
<resource-path>:
+state:
lag_tolerance: <duration_string>

Определение​

Исходные системы могут обновляться чаще, чем требуется пересобирать некоторые нижестоящие модели. Например, модель для ежедневной отчётности не нужно обновлять чаще одного раза в день, даже если новые вышестоящие данные поступают каждый час, тогда как модель для расчёта метрик, доступных клиентам, использующая часть тех же источников, может требовать обновления каждые 30 минут.

lag_tolerance задаёт время, которое dbt State выжидает перед пересборкой узла при изменении вышестоящих данных. Узел пересобирается, только когда выполняются оба условия: с момента его последней сборки прошло больше времени, чем задано в lag_tolerance, и вышестоящие данные изменились с момента этой сборки. Это создаёт буфер, позволяющий экономить вычислительные ресурсы и соблюдать соглашения об уровне обслуживания (SLA) в отношении актуальности данных без ненужных пересборок. Поддерживаются два основных сценария:

  • Согласование сборок с требованиями SLA: lag_tolerance позволяет напрямую согласовать выполнение моделей с требованиями SLA к актуальности данных, отделяя частые изменения вышестоящих данных от нижестоящих моделей с менее строгими требованиями к актуальности.
  • Экономия вычислительных ресурсов при нарушениях SLA вышестоящих зависимостей: lag_tolerance защищает ваш бюджет на вычисления при нарушениях SLA по актуальности, предотвращая затратные пересборки нижестоящих моделей на неизменившихся данных, когда вышестоящая зависимость не соответствует своему SLA по актуальности.

Конфигурация lag_tolerance принимает два типа значений:

  • Строки длительности в формате <number><unit>:

    Единица измеренияДопустимые значения
    Секундыs, second, seconds
    Минутыm, minute, minutes
    Часыh, hour, hours
    Дниd, day, days
    Неделиw, week, weeks
  • Выражения Jinja — lag_tolerance вычисляется как шаблон Jinja, поэтому для динамического задания допустимых задержек можно использовать любые переменные контекста dbt (target, var(), env_var()). Это удобно для задания разных допустимых задержек в разных окружениях без дублирования блоков конфигурации:

    lag_tolerance: "{{ '4h' if target.name == 'prod' else '7d' }}"

Когда узел пересобирается​

dbt State пересобирает узел, только когда выполняются оба условия. Если хотя бы одно из них не выполняется, используется существующий узел:

УсловиеЧто оно означает
Допустимая задержка истеклаС момента последней сборки узла прошло больше времени, чем задано в его lag_tolerance.
Вышестоящие данные изменилисьХотя бы в одной вышестоящей зависимости появились новые данные с момента этой сборки.
lag_tolerance задаёт минимальный интервал между пересборками

lag_tolerance определяет, как часто узел может пересобираться, а не то, насколько актуальными должны быть его вышестоящие данные.

Пример​

Допустим, у вас есть задание, которое запускается каждые 30 минут, для модели задана допустимая задержка 45m, а последняя сборка состоялась в 08:00. Новые вышестоящие данные поступили в 08:20.

Запуск заданияВремя с последней сборкиЕсть новые вышестоящие данные с момента последней сборки?Результат
08:3030mДаПовторное использование: допустимая задержка ещё не истекла.
09:0060mДаПересборка: оба условия выполнены.
09:3030mНетПовторное использование: допустимая задержка ещё не истекла, а вышестоящие данные не изменились.
10:0060mНетПовторное использование: вышестоящие данные не изменились с 09:00.

Данные, поступившие в 08:20, ожидали обработки до 09:00. Это был первый запуск, при котором с момента сборки прошло больше 45m и вышестоящие данные изменились. В 10:00 с момента сборки прошло достаточно времени, но, поскольку после 09:00 новые вышестоящие данные не поступали, dbt повторно использовал узел.

Чтобы пересобирать узел при каждом изменении его вышестоящих данных, установите lag_tolerance в 0s:

state:
lag_tolerance: 0s

Когда применяется lag_tolerance​

lag_tolerance применяется только к проверкам актуальности данных. Нижестоящая модель всё равно пересобирается до истечения допустимой задержки, если скомпилированный SQL вышестоящей модели изменился с момента последнего запуска, независимо от настройки lag_tolerance.

Это часто происходит с инкрементальными моделями. При первом запуске инкрементальная модель выполняет полную загрузку без предложения WHERE. При последующих запусках is_incremental() возвращает true и добавляется фильтр, что изменяет скомпилированный SQL. dbt State определяет это как изменение запроса вышестоящей модели и пересобирает все нижестоящие модели, даже те, для которых lag_tolerance ещё не истёк.

Например, fct_orders — инкрементальная модель, от которой зависит agg_orders_daily:

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 переходит от полной загрузки к инкрементальному запуску, её скомпилированный SQL меняется. При этом запуске agg_orders_daily пересобирается, несмотря на заданный для неё lag_tolerance в 3 часа.

подсказка

Чтобы помочь вам настроить значения lag_tolerance, страница dbt State на dbt platform предоставляет рекомендации по допустимому отставанию на основе истории сборок ваших моделей за последние 30 дней, позволяя определить, для каких моделей будет полезно увеличить допустимое отставание.

Значение по умолчанию​

Если вы не задаёте lag_tolerance, dbt State использует 45m (45 минут).

Примеры​

Использование разных допустимых задержек в разных окружениях​

Используйте выражение Jinja, чтобы задать меньшую допустимую задержку в промышленном окружении и большую — в остальных. Это позволяет поддерживать актуальность данных в промышленном окружении и сокращать ненужные пересборки при разработке:

dbt_project.yml
models:
+state:
lag_tolerance: "{{ '4h' if target.name == 'prod' else '7d' }}"

В этом примере модели для целевого окружения prod пересобираются, когда с момента последней сборки прошло больше 4 часов и вышестоящие данные изменились. Во всех остальных окружениях модели пересобираются, когда с момента последней сборки прошло больше 7 дней и вышестоящие данные изменились.

Изменение допустимой задержки в зависимости от дня недели​

Используйте выражение Jinja, чтобы определить день недели и задать более строгую допустимую задержку в будни, чем в выходные:

dbt_project.yml
models:
+state:
lag_tolerance: "{{ '24h' if modules.datetime.datetime.today().weekday() in (5, 6) else '1h' }}"

В этом примере модели пересобираются, когда с момента последней сборки прошло больше 1 часа (с понедельника по пятницу) или больше 24 часов (с субботы по воскресенье) и вышестоящие данные изменились.

Применение разных допустимых задержек к разным папкам​

Задайте разные допустимые задержки для разных частей проекта, указав соответствующие папки:

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

Связанная документация​

Нашли ошибку?

0
Loading