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

Подход на основе только представлений для максимальной актуальности данных

Далее приведены примеры для Snowflake

На этой странице в примерах кода используется Snowflake, но подход на основе только представлений можно адаптировать и для других хранилищ данных.

Для некоторых рабочих нагрузок самый простой подход, наиболее близкий к работе «в реальном времени», — материализовать всё в виде представлений над непрерывно обновляемой исходной таблицей. Если преобразования очень легковесны, а источник уже обновляется почти в реальном времени, такой подход позволяет практически не увеличивать задержку источника.

Когда использовать подход на основе только представлений​

Используйте этот подход, если:

  • Актуальность источника уже «достаточно хорошая» (например, сервис загрузки данных или операционная система записывает данные в таблицу хранилища каждые несколько секунд или минут).
  • Преобразования очень легковесны, например:
    • Простой выбор или переименование столбцов
    • Одно-два соединения с небольшой справочной таблицей
    • Минимальное использование ресурсоёмких агрегаций или оконных функций либо их полное отсутствие
  • Для вас важнее всего сохранить задержку исходной таблицы, и вы готовы пожертвовать некоторой производительностью запросов при чтении.
  • Лучше всего этот подход подходит для небольших и средних таблиц с простыми запросами.

Типичные примеры:

  • Дашборды с текущим состоянием системы (например, активными пользовательскими сессиями, текущей длиной очереди или последними сигналами активности устройств), где необходимо сразу видеть самые свежие данные.
  • Данные событий, которые вы передаёте в другие инструменты с минимальными преобразованиями (необработанные данные с небольшой нормализацией, например приведением имён полей к единому виду или добавлением нескольких справочных полей).

Если логика преобразований становится сложнее, от данных зависят несколько команд или вам нужен более точный контроль затрат и производительности, переходите на инкрементальные модели или динамические таблицы / материализованные представления. Оставьте этот подход для самых небольших сценариев, наиболее чувствительных к задержке.

Предположения​

Примеры на этой странице предполагают следующую конфигурацию:

  • Внешняя по отношению к dbt система (ETL, потоковый конвейер, приложение) уже записывает данные в таблицу хранилища, например raw.realtime_events или ops.active_sessions, и эта таблица соответствует вашему соглашению об уровне обслуживания в части задержки.
  • Прямые запросы к этой таблице приемлемы с точки зрения производительности и стоимости при ожидаемом количестве одновременных запросов.
  • Вам не нужно, чтобы dbt сохранял промежуточные таблицы; для вас важны прежде всего:
    • Единообразная логика SQL (именование столбцов, приведение типов)
    • Тесты, контракты и происхождение данных
    • Exposures для BI-инструментов и других потребителей данных

Все модели dbt в этом подходе материализуются как представления, а не как таблицы или инкрементальные модели.

Пример реализации​

Ниже приведён пример реализации подхода на основе только представлений со следующей структурой:

Определение исходной таблицы​

# models/sources.yml
version: 2

sources:
- name: raw
schema: raw
tables:
- name: realtime_events
description: "Непрерывно обновляемая таблица событий из потокового конвейера."
loaded_at_field: event_ts

Представление промежуточного слоя​

-- models/staging/stg_realtime_events.sql
{{ config(
materialized = 'view'
) }}

select
event_id,
event_ts::timestamp_ntz as event_ts, -- Синтаксис Snowflake для приведения типов
to_date(event_ts) as event_date,
user_id,
event_type,
payload
from {{ source('raw', 'realtime_events') }};

Определение представления предметной области​

-- models/marts/vw_realtime_events_enriched.sql
{{ config(
materialized = 'view'
) }}

with base as (
select *
from {{ ref('stg_realtime_events') }}
),

user_dim as (
select
user_id,
user_segment,
signup_date
from {{ ref('dim_user') }} -- может быть таблицей или инкрементальной моделью
)

select
b.event_id,
b.event_ts,
b.event_date,
b.user_id,
u.user_segment,
b.event_type,
b.payload
from base as b
left join user_dim as u
on b.user_id = u.user_id;

Инструменты-потребители запрашивают analytics.vw_realtime_events_enriched. Пока raw.realtime_events непрерывно обновляется, эта цепочка представлений обеспечивает ту же актуальность данных, что и источник.

Преимущества​

  • Максимальная актуальность: представление отражает новые данные сразу после их поступления в raw.realtime_events.
  • Простота эксплуатации: не нужно настраивать инкрементальную логику и запускать дополнительное задание dbt только ради поддержания актуальности данных. При этом задания для тестов, документации и других задач по-прежнему нужно запускать по расписанию.
  • Оптимально для небольших наборов данных: подход хорошо работает с небольшими таблицами и простыми запросами. Вычисление представления на лету выполняется быстро и с небольшими затратами.

Ограничения и риски​

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

Не масштабируется для ресурсоёмких преобразований​

Если логика усложняется и включает соединения больших таблиц, длинные цепочки представлений или ресурсоёмкие агрегации, вы быстро столкнётесь с проблемами производительности:

  • Каждый запрос должен заново выполнять всю логику.
  • Хранилищу приходится каждый раз оптимизировать и выполнять всю цепочку представлений.

В таких случаях используйте один из следующих вариантов:

Нет «зафиксированных» промежуточных таблиц​

Поскольку всё реализовано в виде представлений:

  • Нет сохранённого промежуточного слоя для отладки или профилирования данных.
  • Нельзя легко «повторно выполнить вчерашнюю логику», если вышестоящие данные изменились: всё всегда отражает текущее состояние.

Чувствительность к изменениям схемы​

Изменения схемы исходной таблицы немедленно распространяются по всей цепочке представлений, что:

  • Может нарушить работу BI-инструментов, использующих эти данные, при удалении столбцов или изменении типов.
  • Повышает важность тестов и контрактов моделей, поскольку нет границы между пакетными обработками, на которой можно обнаружить проблемы до того, как с ними столкнутся пользователи.

Возможное влияние на операционные системы​

Если непрерывно обновляемый источник сам является рабочей операционной базой данных (а не таблицей приёма данных в хранилище), важно не перегрузить его аналитическими запросами. В большинстве случаев рекомендуется:

  1. Сначала реплицировать данные в таблицу хранилища (Snowflake, BigQuery, Databricks и т. д.).
  2. Применять этот подход на основе только представлений внутри хранилища, а не непосредственно в системе оперативной обработки транзакций (OLTP).

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

0
Loading