Data Vault — одна из самых популярных и устоявшихся методологий моделирования архитектуры данных. Но в ситуации, когда на входе несколько десятков внутренних и внешних источников, а сверху прежней «снежинки» построены уже сотни бизнес-витрин, переход на Data Vault «на ходу» может оказаться затруднительным и ресурсозатратным. Поэтому мы в СберЗдоровье пошли другим путём.

Меня зовут Иван Гуляев. Я Senior DE с уклоном в архитектуру и моделирование данных в CберЗдоровье — MedTech-компании №1 в России. В этой статье я расскажу, как мы с помощью самописного приложения, каталога данных (Datahub) и связки dbt + Automate-dv построили Data Vault на Trino.

Немного о Data Vault, Data Governance, Datahub

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

  • архитектура, заложенная на начальном этапе, не заточена под дальнейшее масштабирование;

  • все домены живут в своём мире;

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

Принцип решения этой проблемы универсален — нанять больше людей, закупить более мощное железо, переехать из Greenplum на Trino, используя популярный ныне подход с разделением storage и compute. Не менее важно — пересмотреть подход к моделированию и архитектуре данных. И здесь многие оправданно выбирают концепцию Data Vault, которая:

  • позволяет достаточно гибко подстраиваться под изменчивые исходные таблицы;

  • даёт возможность грузить данные по частям;

  • поддерживает историчность SCD-2 на таблицах-сателлитах из коробки;

  • имеет множество модификаций и расширений (Multi-active satellites, XTS, PIT и прочие).

Нюанс в том, что Data Vault внедряется без проблем только на ранних этапах развития ИТ в компании. Но когда в компании уже много разношерстных источников, на которых уже выстроена целая система с бизнес-отчетностью, процесс переезда на Data Vault начинает требовать выделенную MDM/EDW-команду, которая будет заниматься детективной и архитектурной работой:

  • распутывать все связи между данными из исходных таблиц-источников для построения линков;

  • выделять основные бизнес-сущности в хабы, проводя созвоны с бизнесом, пользователями, продакт-менеджерами, продуктовыми и бизнес-аналитиками;

  • продумывать архитектуру конечного решения (raw data vault, business data vault);

  • адаптировать текущие инструменты или изобретать новые для построения Data Vault.

Процесс весьма кропотливый и ресурсоёмкий, однако некоторые элементы можно облегчить и даже автоматизировать.

В такой ситуации невозможно переоценить важность развития подходов Data Governance в компании. Ведь именно благодаря Data Governance данные и аналитика становятся более прозрачными и контролируемыми, так как вся основная документация и метаданные из платформы данных лежат в вашем каталоге — например, в Datahub. 

Datahub по своей сути полезен для всех пользователей: 

  • аналитики могут оценить и изучить структуру исходных таблиц из источников, проставить теги и описания для таблиц и колонок;

  • инженеры — посмотреть Lineage из источника до Kafka и бизнес-витрин, оценить результаты тестов по качеству данных;

  • менеджеры — посмотреть на внутрянку таблиц в их домене.

И именно Datahub становится единым источником правды и метаданных: к серверу можно подключиться по протоколу GraphQL и получить практически любую нужную информацию про платформу данных.

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

query getDatasetSchema {
  dataset(
	urn: "urn:li:dataset:(urn:li:dataPlatform:mysql,my_source_db.my_source_table,PROD)"
  ) {
	urn
	name
	schemaMetadata {
  	foreignKeys {
    	name
    	sourceFields {
      	fieldPath
    	}
    	foreignFields {
      	fieldPath
    	}
    	foreignDataset {
      	urn
    	}
  	  }
	}
  }
}

Потенциально можно создать базу из таких запросов и построить свой персонализированный фронтенд для расширения функционала Datahub. Именно это мы частично и воплотили в Transform App.

Больше кейсов и новых решений нашей команды — в ТГ-канале SberHealth IT ;)

Выбор платформы для Data Vault

Одним из ключевых вопросов при внедрении Data Vault является выбор платформы для построения и определения алгоритма поставки данных в Data Vault из источников.

  • За основу мы взяли концепт CDC (Change Data Capture), который обеспечивается связкой «Debezium + Kafka-Connect»: с их помощью можно практически в реальном времени стримить данные в целевую платформу, минимизируя при этом нагрузку из БД-источников за счёт чтения из журнала транзакций (по сравнению с традиционным ETL по курсору).

  • В качестве целевой платформы подойдет любая DWH БД, которая может совладать с большим количеством JOIN'ов (без них в Data Vault не обойтись). Мы выбрали комбинацию Trino/S3/Iceberg — с учетом возможности горизонтального и вертикального масштабирования системы, эта связка является одной из самых производительных и гибких в современных реалиях.

Дальнейшие шаги в построении Data Vault: Automate-DV и первая версия Transform App в виде терминального приложения

В платформе данных СберЗдоровья используется dbt для трансформации данных и построения бизнес-витрин. Экосистема dbt бурно развивается, есть много различных плагинов и расширений: начиная от DQ-пакетов (dbt expectations, dbt project evaluator) и заканчивая полноценными фреймворками для построения Data Vault.

Одним из таких решений является Automate-DV — набор dbt-шаблонов, которые позволяют построить все основные сущности raw data vault слоя: stage, hub, links, satellites, refs, t-links и другие.

Код модели типа satellites выглядит следующим образом:

{{ config(materialized='incremental') }}
{%- set yaml_metadata -%}

source_model: 'v_stg_transactions'

src_pk: 'TRANSACTION_HK'
src_fk: 
    - 'CUSTOMER_HK'
    - 'ORDER_HK'
src_payload:
    - 'TRANSACTION_NUMBER'
    - 'TRANSACTION_DATE'
    - 'TYPE'
    - 'AMOUNT'
src_eff: 'EFFECTIVE_FROM'
src_ldts: 'LOAD_DATETIME'
src_source: 'RECORD_SOURCE'

{%- endset -%}

{% set metadata_dict = fromyaml(yaml_metadata) %}

{{ automate_dv.t_link(src_pk=metadata_dict["src_pk"],
                      src_fk=metadata_dict["src_fk"],
                      src_payload=metadata_dict["src_payload"],
                      src_eff=metadata_dict["src_eff"],
                      src_ldts=metadata_dict["src_ldts"],
                      src_source=metadata_dict["src_source"],
                      source_model=metadata_dict["source_model"]) }}

Примечательно, что из коробки нет поддержки Trino, но код открыт и его можно модифицировать: изменить поведение, добавить новые макросы или подвиды Data Vault сущностей и даже внедрить поддержку БД, которых нет изначально (что мы и сделали для Trino).

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

Для решения этого вопроса команда наших дата-инженеров начала разработку Transformation Framework — CLI-приложения, которое позволяет подключиться к Datahub через GraphQL, загрузить метаданные нужной таблицы, проставить все главные и внешние ключи, кастомизировать название домена и другие параметры. На выходе из этого CLI-приложения мы получаем заполненные dbt-модели для Automate-DV.

Старый CLI интерфейс
Старый CLI интерфейс

Фунционально? Да.

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

Терминальное приложение было в проде несколько месяцев, и за это время мы перенесли с его помощью несколько доменов. Но у нас еще оставалось несколько точек роста, которые можно было реализовать. Например:

  • повысить наглядность; 

  • улучшить автоматизацию редактирования уже существующих моделей;

  • упростить построение навигации по CLI.

В результате было принято решение сделать приложение с полноценным UI-интерфейсом.

Переход на следующий этап: Transform App

Для разработки приложения под наши задачи мы взяли за основу React с библиотекой xyflow для отрисовки Canvas с ERD-таблиц. В результате получили функциональное и интуитивно понятное решение.

Алгоритм работы с ним довольно прост.

  1. Для начала пользователь должен выбрать из Datahub (кстати, подключение по тому же GraphQL) таблицы, которые нужно перенести в Data Vault / в шаблоны Automate-DV:

    При желании можно настроить алиас для схемы (если на бэкенде источник называется техническим именем, а загрузить нужно под бизнесовым), включить поддержку CDC: так Transform App сходит в Datahub и постарается найти загруженные таблички после CDC-пайплайна, чтобы подставить их в dbt'шный source.yml.

  2. После выбора таблиц открывается основное приложение с канвасом и настройками Data Vault:

    Здесь у пользователя есть следующие возможности:

  • добавить связи между таблицами, если их нет в БД источнике;

  • выключить связи между таблицами, которые есть в БД источнике (например, если есть chat_messages и колонка reply_id ссылается на id в этой же таблице)

  • выключить генерацию хабов/сателлитов для определенных таблиц;

  • выбрать совсем другой тип сущности Data Vault — T-Link, Ref — которые не потребуется разбивать на основную связку из хаба/линка/сателлита.

Отобразить можно хоть все таблицы, правда в текущей реализации reactflow будет проседать по FPS при 50+ таблиц сразу. 

Примечание: Здесь есть пространство для оптимизации: есть смысл оценить альтернативные библиотеки, вроде cytoscape или даже либы с поддержкой WebGL для отрисовки нод на GPU.

  1. После нажатия на кнопку «Сгенерировать» получаем готовые для Automate-DV dbt файлы, которые можно из коробки сразу вставить в проект и материализовать.

Так же генерируются сопутствующие .yml файлы с метаданными и базовыми тестами (описания колонок тоже выгружаются из Datahub, если есть):

Полученные результаты и планы на будущее

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

Безусловно, текущую систему можно (и нужно) дорабатывать. Так, например, в будущем мы планируем:

  • записывать метаданные из приложения в Custom Properties в Datahub, чтобы хранить кастомные связи, виды дата-волта и прочие метаданные в отдельном поле; ()

  • добавить возможность дробить таблицы на несколько хабов/линков/сателлитов, либо же наоборот — объединять в один хаб (частично это уже можно сделать, выключив хаб в настройках конкретной таблицы и оставив сателлит);

  • добавить другие виды сущностей Data Vault;

  • сделать полноценный онбординг при первом открытии с обучением пользователя базовым понятиям Data Vault;

  • добавить подсказки ИИ для нахождения связей на основе метаданных загруженных таблиц.

Однако даже в текущем формате Transform App уже значительно упрощает взаимодействие и построение Data Vault моделей. И дальше — больше. О том, что получится в итоге, обязательно расскажем в одной из следующих статей.