Привет! Сегодня речь пойдет о семантическом слое метрик. В публикации рассмотрим на практике грани интересной темы:

  • Что такое семантический слой, и в чем разница между Метрикой и Витриной данных.

  • Пути формирования метрик: SQL (ad-hoc), UI, dbt Metrics, Cube.

  • Примеры декларативной конфигурации в YAML и использования метрик.

  • На что обращать внимание при выборе решения: Стек технологий, Доступность vs. Выразительнось, Гибкость vs. Скорость.

Метрика - это нечто измеримое, представляющее интерес

Чем метрика отличается от витрины данных?

  • Витрины данных - это статичные таблицы

  • Витрины данных - основной результаты шага преобразования данных (T из ELT)

  • Витрины данных создаются для того, чтобы сделать расчет метрик понятным и простым

  • Метрики, в отличие от Витрин, имеют динамический характер: функция агрегации / гранулярность даты / набор измерений / применяемые фильтры

Как можно получить метрики?

Написание SQL-запросов к Витринам данных

  • С первого взгляда, простой способ, который однако очень просто может превратиться в сложночитаемый код

  • Требуются навыки SQL, часто - продвинутые: CTE, window functions, CASE expressions

  • В основном ad-hoc - ответ здесь и сейчас на конкретный вопрос. Новый вопрос - новый SQL-код

User Interface BI-инструментов

  • Простой и интуитивно понятный способ конфигурации метрик

  • Используется в большинстве BI-решений

Специальные языки, связанные с BI-инструментами (LookML)

  • Широкие возможности конфигурирования

  • Но привязка к конкретному решению (Vendor lock-in)

Семантический слой (Semantic Layer)

  • Прослойка между СУБД и бизнес-пользователями

  • Централизация бизнес-логики — определение метрик (декларативно) в одном месте

  • Разделение аналитического бэкенда и потребителей

  • Продвинутые паттерны моделирования (dimensions, segments, joins, drill-downs)

  • Обращение через API из множества инструментов: BI, Notebooks, REST, Embedded analytics

Использование dbt Metrics

dbt Metrics - семантический слой формирования метрик от dbt Labs.

Для использования потребуется установить модуль dbt-labs/metrics

packages:
  - package: dbt-labs/metrics
    version: [">=1.0.0", "<2.0.0"]

Метрики задаются декларативно в YAML файле

version: 2

metrics:

  - name: costs
    label: 'Costs spent (RUB)'
    model: ref('f_tracker')
    description: ''

    calculation_method: sum
    expression: cost

    timestamp: dt
    time_grains: [day, week, month, quarter, year]

    dimensions: [traffic_grouping, traffic_source, traffic_medium, traffic_campaign, device_category, location_country]

  - name: clicks
    label: 'Clicks'
    model: ref('f_tracker')
    description: ''

    calculation_method: sum
    expression: clicks

    timestamp: dt
    time_grains: [day, week, month, quarter, year]

    dimensions: [traffic_grouping, traffic_source, traffic_medium, traffic_campaign, device_category, location_country]

  - name: cpc
    label: 'Cost per Click'
    description: ''

    calculation_method: derived
    expression: "{{ metric('costs') }} / {{ metric('clicks') }}"

    timestamp: dt
    time_grains: [day, week, month, quarter, year]

    dimensions: [traffic_grouping, traffic_source, traffic_medium, traffic_campaign, device_category, location_country]

Описав метрику, вы можете обращаться к ней из других моделей dbt

{{
    config (
      materialized='table'
    )
}}


select 
    * 
from {{ metrics.calculate(
        metric_list=[metric('costs')]
        , grain='month'
        , dimensions=['traffic_source']
        , date_alias='reporting_date'
        )
    }}

Использование Cube

Cube - инструмент формирования семантического слоя со множеством возможностей.

Развернуть инструмент можно через Docker.

version: '2'
services:

  cube:
    image: cubejs/cube:latest
    ports:
      - 4000:4000
      - 15432:15432
    env_file:
      - .env      
    volumes:
      - .:/cube/conf

Метрики задаются декларативно в формате YAML или JS

cubes:
  - name: f_tracker
    sql: SELECT * FROM analytics.f_tracker
    measures:
      - name: costs
        sql: cost
        type: sum
      - name: clicks
        sql: clicks
        type: sum
      - name: CPC
        sql: '{CUBE.costs} / nullif(coalesce({CUBE.clicks}, 1), 0)'
        type: number
    dimensions:
      - name: date
        sql: 'dt'
        type: time
      - name: traffic_grouping
        sql: traffic_grouping
        type: string
      - name: traffic_source
        sql: traffic_source
        type: string
      - name: traffic_medium
        sql: traffic_medium
        type: string
      - name: traffic_campaign
        sql: traffic_campaign
        type: string
      - name: device_category
        sql: device_category
        type: string
      - name: location_country
        sql: location_country
        type: string
    dataSource: default

Для запроса метрик доступны несколько интерфейсов:

  • SQL API

  • REST API

  • GraphQL API

Сценарии использования

Материализация метрик в отдельные таблицы.

Когда это выгодно?

  • Предположим, у вас много метрик (KPI): 15+

  • Есть заранее известный набор измерений/фильтров

  • Большие/дорогие таблицы для частых запросов

  • Вы можете предварительно агрегировать данные

  • Технически, это dbt-модели со ссылками на метрики

  • Звучит как старый добрый OLAP-куб

Динамические запросы метрик через Сервер метрик

Основной способ использования Семантического слоя.

  • Необходимо иметь Сервер, который будет коммуницировать запрос метрик в понятные СУБД скрипты и отдавать результаты

  • Интерактивная аналитика (например, через BI-инструмент)

На что обращать внимание при выборе решения

Стек технологий, на котором построено ваше решение

Прежде всего, попробуй ответить на вопрос: Какую проблему вы пытаетесь решить? Для чего вам необходим семантический слой?

Далее пройдите по списку вопросов:

  • Используете ли вы dbt? (низкий порог входа в dbt Metics)

  • Какой инструмент BI вы используете? (Looker уже имеет это всё)

  • Предпочтительно ли для вас использование Open Source Software? (прозрачность, доработка кода под себя)

  • Можете ли вы развернуть решение на своей инфраструктуре? (Или хотите SaaS)

Например, сейчас использование dbt Cloud Proxy Server доступно только для пользователей Snowflake и dbt Cloud.

Компромисс между гибкостью и скоростью

Кэширование - отличный паттерн. При предварительной агрегации (кэшировании) вы экономите время и ресурсы (деньги). Но при всех его преимуществах, он также вносит ряд усложнений:

  • Вы не можете предагрегировать все возможные варианты ответов (либо это будет дорого)

  • Кэш имеет свойство протухать со временем (исходные данные меняются)

Лучшей практикой является кэширование наиболее часто используемых запросов метрик.

  • Cube поддерживает предварительную агрегацию

  • dbt Metrics - нет, однако вы можете использовать dbt Metrics для материализации в моделях (аналог OLAP-куба)

Доступность против Выразительности

Главная особенность dbt Metrics на текущий момент - отсутствие понятния связи таблиц (foreign key). Зато конифгурация и использование таких метрик выглядит проще для неискушенного пользователя.

  • Cube (как и LookML) оперирует абстракциями SQL: таблицы, соединения.

  • dbt Metrics делает ставку на бизнес-сущности.

Что еще изучить по теме?

Приходите учиться использовать самые современные, популярные, востребованные инструменты на курсе Analytics Engineer:

  • Extract - Load - Transform

  • dbt: from basics to advanced

  • Deployment, Continuous Integration, Monitoring

  • Business Intelligence

  • DWH Advanced toolkit

Полезные материалы: