EDA-архитектура данных в DWH: моделирование и реализация

EDA-архитектура данных в DWH: моделирование и реализация

Чем схема, применяемая к данным, при чтении отличается от схемы при записи, почему она вызывает GIGO-проблему в Data Lake, и как применить принципы функциональной дата-инженерии к архитектуре данных, управляемой событиями.

Схема при чтении или при записи: главное отличие NoSQL-решений от реляционных СУБД

NoSQL-решения и Apache Hadoop реализуют стратегию «схема при чтении», которая отличается от классических методов моделирования данных, когда данные могли попасть в хранилище только в случае соответствия заранее определенной схеме. Это обеспечивало согласованность данных, однако, снижало гибкость системы. В схеме при чтении к данным применяется схема по мере их извлечения из сохраненного местоположения, а не по мере поступления. Это увеличивает объем работы при вычислениях с данными за счет упрощения процессов их загрузки в хранилище.

Схема при записи лучше подходит для получения чистых и непротиворечивых наборов данных, поэтому именно эта схема исторически использовалась при проектировании хранилищ данных (Data Warehouse, DWH), которые в упрощенном виде можно рассматривать как огромные реляционные СУБД. Схема при чтении обеспечивает более гибкую организацию данных, упрощая работу с ними через создание различных представлений. Схема при чтении характерна для озер данных (Data Lake), которые хранят данные с различной структурой для поддержки всех видов бизнес-процессов предприятия.

Однако, по мере роста объема данных, хранящихся в озерах, схема при чтении приводит к проблеме GIGO (Garbage In, Garbage Out), когда в Data Lake собирается слишком много разрозненных и противоречивых друг другу данных. При этом растет сложность управления этими данными, а само поддержка DWH превращается в технический долг вместо того, чтобы быть стратегическим преимуществом data-driven организации. Поэтому современная дата-инженерия отходит от классического моделирования данных для DWH, стремясь разделять хранилище и вычислительные ресурсы, чтобы масштабировать их независимо друг от друга, сохраняя воспроизводимость задач в конвейере данных и возможность повторного вычисления.

Для этого в DWH и Data Lake необходим переход от концепции статичных сущностей к архитектуре данных, управляемой событиями (EDA, Event-Driven Architecture), некоторые принципы которой схожи с EDA-архитектурой программных систем, активно используемой в микросервисном подходе, о чем мы недавно писали здесь. Что это означает, и как реализуется, мы рассмотрим далее.

EDA-архитектура данных

В архитектуре данных, управляемой событиями, по-прежнему присутствует понятие сущности (Entity), которое описывает объекты домена как изменяемые данные с первичным ключом: пользователь, продукт и пр. Также появляется понятие события (event), которое представляет собой случившийся факт, а потому является неизменяемыми данными с отметкой времени. Обычно событие описывает какую-то активность, произошедшую в домене, например, пользователь А добавил продукт X в корзину в момент Z. Для связи сущностей с событиями используются таблицы временных разделов, которые поддерживают полную копию текущего состояния объекта для каждого временного раздела. Поскольку сегодня большинство организаций используют облачные объектные хранилища в качестве озера данных, далее также будем придерживаться этого подхода.

Например, в классическом моделировании данных создание сущности пользователь можно представить следующим SQL-запросом:

CREATE TABLE dw.user (
user_id BIGINT, 
user_name STRING, 
created_at DATE
) 
PARTITION BY (ds STRING)
# ds = date timestamp of the snapshot

Типичная файловая структура объектного хранилища на примере AWS S3 будет выглядеть так:

s3://dw/user/2023-12-20/<all users data at the time of snapshot>
s3://dw/user/2023-12-21/<all users data at the time of snapshot>

Создание таблицы с событиями пользовательской активности (user_activity) можно представить так:

CREATE TABLE dw.user (
user_id BIGINT, 
activity_type STRING, 
event_timestamp LONG
) 
PARTITION BY (ds STRING, hour STRING)

# ds = date timestamp of the event
# hour = hour of the event [Assume the events are hourly pipeline]

Типичная файловая структура объектного хранилища также на примере AWS S3 выглядит так:

s3://dw/user_activity/2022-12-20/10/<all users activity data for the hour 10 on 2022-12-20>
s3://dw/user/2022-12-20/11/<all users activity data for the hour 11 on 2022-12-20>

Конвейеры обработки данных сущностей, которые изменяются, могут работать в двух режимах: инкрементальный (incremental snapshot) и полный моментальный снимок (full snapshot).

Подход инкрементального снимка используется в CDC-технологиях  (Change Data Capture) и сохраняет представление объекта по мере его изменения. Инкрементный snapshot проходит несколько дополнительных предварительных шагов, прежде чем взять разделы таблицы отметки времени:

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

Полный моментальный снимок является относительно более простым подходом, когда берется глубокий клон исходных данных и записывается с таблицей версии отметки времени в хранилище данных. Таблица разделов отметки времени оптимизирует процесс конвейера данных, но текущее состояние объекта требует специальных аналитических запросов. В частности, добавление раздела ds в фильтр запроса усложняет его. Упростить такой SQL-запрос помогает логическое представление поверх последнего раздела:

CREATE OR REPLACE VIEW dw.user_latest AS 
  SELECT user_id, user_name, created_at, ds 
  FROM dw.user 
  WHERE 
  ds=<current DateTime partition>;

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

EDA архитектура данных, дата-архитектура примеры курсы обучение, обучение архитекторов данных, DWH Data Lakeпримеры курсы
Сущности и события в EDA-архитектуре данных

Реализовать такой EDA-подход к данным можно в MPP-СУБД Greenplum, которая часто используется в качестве основы для DWH. В частности, события можно хранить в AO-таблицах, оптимизированных для добавления данных, а сущности в хранилище кучи. Подробнее о лучших практиках хранения данных в Greenplum мы писали здесь.

В заключение отметим еще пару преимуществ парадигмы функциональной инженерии данных с EDA-подходом: возможность перемещения во времени как для сущностей, так и для событий, а также сокращение объема работы по предварительному моделированию данных. А благодаря разделению хранения и вычислений отладка конвейеров данных и исправление ошибок выполняются намного быстрее. Однако, принципы функциональной инженерии данных не заменяют ни один из методов моделирования данных. В частности, при проектировании витрин и хранилищ данных имеет смысл использовать подходы Кимбалла и Инмона или Data Vault. А исправить ошибки, сделанные при этом моделировании данных позволяют принципы функциональной дата-инженерии.

Узнайте больше подробностей по проектированию и поддержке современных дата-архитектур в проектах аналитики больших данных на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:

Источники

  1. https://blog.schematalabs.com/functional-data-engineering-a-blueprint-d1b264d9dc61
  2. https://www.techopedia.com/definition/30153/schema-on-read
  3. https://github.com/ananthdurai/schemata#the-garbage-in-garbage-out-gigo-problem